blob: 7d6e758cf47aadd97aeec5ab69385e966d754ba8 [file] [log] [blame]
Jing Zhouff57d862017-03-21 00:54:25 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/iopoll.h>
14#include <linux/slab.h>
15#include <uapi/media/cam_isp.h>
16#include <uapi/media/cam_defs.h>
17
18#include "cam_ife_csid_core.h"
19#include "cam_isp_hw.h"
20#include "cam_soc_util.h"
21#include "cam_io_util.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070022#include "cam_debug_util.h"
Jing Zhouff57d862017-03-21 00:54:25 -070023
24/* Timeout value in msec */
25#define IFE_CSID_TIMEOUT 1000
26
27/* TPG VC/DT values */
28#define CAM_IFE_CSID_TPG_VC_VAL 0xA
29#define CAM_IFE_CSID_TPG_DT_VAL 0x2B
30
31/* Timeout values in usec */
32#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
33#define CAM_IFE_CSID_TIMEOUT_ALL_US 1000000
34
35static int cam_ife_csid_is_ipp_format_supported(
Harsh Shahf7136392017-08-29 12:42:52 -070036 uint32_t in_format)
Jing Zhouff57d862017-03-21 00:54:25 -070037{
38 int rc = -EINVAL;
39
Harsh Shahf7136392017-08-29 12:42:52 -070040 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070041 case CAM_FORMAT_MIPI_RAW_6:
42 case CAM_FORMAT_MIPI_RAW_8:
43 case CAM_FORMAT_MIPI_RAW_10:
44 case CAM_FORMAT_MIPI_RAW_12:
45 case CAM_FORMAT_MIPI_RAW_14:
46 case CAM_FORMAT_MIPI_RAW_16:
47 case CAM_FORMAT_MIPI_RAW_20:
48 case CAM_FORMAT_DPCM_10_6_10:
49 case CAM_FORMAT_DPCM_10_8_10:
50 case CAM_FORMAT_DPCM_12_6_12:
51 case CAM_FORMAT_DPCM_12_8_12:
52 case CAM_FORMAT_DPCM_14_8_14:
53 case CAM_FORMAT_DPCM_14_10_14:
54 rc = 0;
55 break;
56 default:
57 break;
58 }
59 return rc;
60}
61
Harsh Shahf7136392017-08-29 12:42:52 -070062static int cam_ife_csid_get_format_rdi(
63 uint32_t in_format, uint32_t out_format,
64 uint32_t *decode_fmt, uint32_t *plain_fmt)
Jing Zhouff57d862017-03-21 00:54:25 -070065{
66 int rc = 0;
67
Harsh Shahf7136392017-08-29 12:42:52 -070068 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070069 case CAM_FORMAT_MIPI_RAW_6:
Harsh Shahf7136392017-08-29 12:42:52 -070070 switch (out_format) {
71 case CAM_FORMAT_MIPI_RAW_6:
72 *decode_fmt = 0xf;
73 break;
74 case CAM_FORMAT_PLAIN8:
75 *decode_fmt = 0x0;
76 *plain_fmt = 0x0;
77 break;
78 default:
79 rc = -EINVAL;
80 break;
81 }
Jing Zhouff57d862017-03-21 00:54:25 -070082 break;
83 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahf7136392017-08-29 12:42:52 -070084 switch (out_format) {
85 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahea34b602017-09-29 11:42:45 -070086 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -070087 *decode_fmt = 0xf;
88 break;
89 case CAM_FORMAT_PLAIN8:
90 *decode_fmt = 0x1;
91 *plain_fmt = 0x0;
92 break;
93 default:
94 rc = -EINVAL;
95 break;
96 }
Jing Zhouff57d862017-03-21 00:54:25 -070097 break;
98 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -070099 switch (out_format) {
100 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahea34b602017-09-29 11:42:45 -0700101 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700102 *decode_fmt = 0xf;
103 break;
104 case CAM_FORMAT_PLAIN16_10:
105 *decode_fmt = 0x2;
106 *plain_fmt = 0x1;
107 break;
108 default:
109 rc = -EINVAL;
110 break;
111 }
Jing Zhouff57d862017-03-21 00:54:25 -0700112 break;
113 case CAM_FORMAT_MIPI_RAW_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700114 switch (out_format) {
115 case CAM_FORMAT_MIPI_RAW_12:
116 *decode_fmt = 0xf;
117 break;
118 case CAM_FORMAT_PLAIN16_12:
119 *decode_fmt = 0x3;
120 *plain_fmt = 0x1;
121 break;
122 default:
123 rc = -EINVAL;
124 break;
125 }
Jing Zhouff57d862017-03-21 00:54:25 -0700126 break;
127 case CAM_FORMAT_MIPI_RAW_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700128 switch (out_format) {
129 case CAM_FORMAT_MIPI_RAW_14:
130 *decode_fmt = 0xf;
131 break;
132 case CAM_FORMAT_PLAIN16_14:
133 *decode_fmt = 0x4;
134 *plain_fmt = 0x1;
135 break;
136 default:
137 rc = -EINVAL;
138 break;
139 }
Jing Zhouff57d862017-03-21 00:54:25 -0700140 break;
141 case CAM_FORMAT_MIPI_RAW_16:
Harsh Shahf7136392017-08-29 12:42:52 -0700142 switch (out_format) {
143 case CAM_FORMAT_MIPI_RAW_16:
144 *decode_fmt = 0xf;
145 break;
146 case CAM_FORMAT_PLAIN16_16:
147 *decode_fmt = 0x5;
148 *plain_fmt = 0x1;
149 break;
150 default:
151 rc = -EINVAL;
152 break;
153 }
Jing Zhouff57d862017-03-21 00:54:25 -0700154 break;
155 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahf7136392017-08-29 12:42:52 -0700156 switch (out_format) {
157 case CAM_FORMAT_MIPI_RAW_20:
158 *decode_fmt = 0xf;
159 break;
160 case CAM_FORMAT_PLAIN32_20:
161 *decode_fmt = 0x6;
162 *plain_fmt = 0x2;
163 break;
164 default:
165 rc = -EINVAL;
166 break;
167 }
Jing Zhouff57d862017-03-21 00:54:25 -0700168 break;
169 case CAM_FORMAT_DPCM_10_6_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700170 *decode_fmt = 0x7;
171 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700172 break;
173 case CAM_FORMAT_DPCM_10_8_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700174 *decode_fmt = 0x8;
175 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700176 break;
177 case CAM_FORMAT_DPCM_12_6_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700178 *decode_fmt = 0x9;
179 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700180 break;
181 case CAM_FORMAT_DPCM_12_8_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700182 *decode_fmt = 0xA;
183 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700184 break;
185 case CAM_FORMAT_DPCM_14_8_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700186 *decode_fmt = 0xB;
187 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700188 break;
189 case CAM_FORMAT_DPCM_14_10_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700190 *decode_fmt = 0xC;
191 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700192 break;
193 default:
Harsh Shahf7136392017-08-29 12:42:52 -0700194 rc = -EINVAL;
195 break;
196 }
197
198 if (rc)
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530199 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d",
Harsh Shahf7136392017-08-29 12:42:52 -0700200 in_format, out_format);
201
202 return rc;
203}
204
205static int cam_ife_csid_get_format_ipp(
206 uint32_t in_format,
207 uint32_t *decode_fmt, uint32_t *plain_fmt)
208{
209 int rc = 0;
210
211 CAM_DBG(CAM_ISP, "input format:%d",
212 in_format);
213
214 switch (in_format) {
215 case CAM_FORMAT_MIPI_RAW_6:
216 *decode_fmt = 0;
217 *plain_fmt = 0;
218 break;
219 case CAM_FORMAT_MIPI_RAW_8:
220 *decode_fmt = 0x1;
221 *plain_fmt = 0;
222 break;
223 case CAM_FORMAT_MIPI_RAW_10:
224 *decode_fmt = 0x2;
225 *plain_fmt = 0x1;
226 break;
227 case CAM_FORMAT_MIPI_RAW_12:
228 *decode_fmt = 0x3;
229 *plain_fmt = 0x1;
230 break;
231 case CAM_FORMAT_MIPI_RAW_14:
232 *decode_fmt = 0x4;
233 *plain_fmt = 0x1;
234 break;
235 case CAM_FORMAT_MIPI_RAW_16:
236 *decode_fmt = 0x5;
237 *plain_fmt = 0x1;
238 break;
239 case CAM_FORMAT_MIPI_RAW_20:
240 *decode_fmt = 0x6;
241 *plain_fmt = 0x2;
242 break;
243 case CAM_FORMAT_DPCM_10_6_10:
244 *decode_fmt = 0x7;
245 *plain_fmt = 0x1;
246 break;
247 case CAM_FORMAT_DPCM_10_8_10:
248 *decode_fmt = 0x8;
249 *plain_fmt = 0x1;
250 break;
251 case CAM_FORMAT_DPCM_12_6_12:
252 *decode_fmt = 0x9;
253 *plain_fmt = 0x1;
254 break;
255 case CAM_FORMAT_DPCM_12_8_12:
256 *decode_fmt = 0xA;
257 *plain_fmt = 0x1;
258 break;
259 case CAM_FORMAT_DPCM_14_8_14:
260 *decode_fmt = 0xB;
261 *plain_fmt = 0x1;
262 break;
263 case CAM_FORMAT_DPCM_14_10_14:
264 *decode_fmt = 0xC;
265 *plain_fmt = 0x1;
266 break;
267 default:
268 CAM_ERR(CAM_ISP, "Unsupported format %d",
269 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700270 rc = -EINVAL;
271 }
272
Harsh Shahf7136392017-08-29 12:42:52 -0700273 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
274 *decode_fmt, *plain_fmt);
275
Jing Zhouff57d862017-03-21 00:54:25 -0700276 return rc;
277}
278
279static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
280 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
281 uint32_t res_type)
282{
283 int rc = 0;
284 struct cam_ife_csid_cid_data *cid_data;
285 uint32_t i = 0, j = 0;
286
287 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
288 if (csid_hw->cid_res[i].res_state >=
289 CAM_ISP_RESOURCE_STATE_RESERVED) {
290 cid_data = (struct cam_ife_csid_cid_data *)
291 csid_hw->cid_res[i].res_priv;
292 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
293 if (cid_data->tpg_set) {
294 cid_data->cnt++;
295 *res = &csid_hw->cid_res[i];
296 break;
297 }
298 } else {
299 if (cid_data->vc == vc && cid_data->dt == dt) {
300 cid_data->cnt++;
301 *res = &csid_hw->cid_res[i];
302 break;
303 }
304 }
305 }
306 }
307
308 if (i == CAM_IFE_CSID_CID_RES_MAX) {
309 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700310 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
311 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700312 rc = -EINVAL;
313 }
314
315 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
316 if (csid_hw->cid_res[j].res_state ==
317 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
318 cid_data = (struct cam_ife_csid_cid_data *)
319 csid_hw->cid_res[j].res_priv;
320 cid_data->vc = vc;
321 cid_data->dt = dt;
322 cid_data->cnt = 1;
323 csid_hw->cid_res[j].res_state =
324 CAM_ISP_RESOURCE_STATE_RESERVED;
325 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700326 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700327 csid_hw->hw_intf->hw_idx,
328 csid_hw->cid_res[j].res_id);
329 break;
330 }
331 }
332
333 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700334 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
335 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700336 rc = -EINVAL;
337 }
338 }
339
340 return rc;
341}
342
343
344static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
345{
346 struct cam_hw_soc_info *soc_info;
347 struct cam_ife_csid_reg_offset *csid_reg;
348 int rc = 0;
349 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
350 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
351
352 soc_info = &csid_hw->hw_info->soc_info;
353 csid_reg = csid_hw->csid_info->csid_reg;
354
355 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700356 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
357 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700358 csid_hw->hw_info->hw_state);
359 return -EINVAL;
360 }
361
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700362 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700363 csid_hw->hw_intf->hw_idx);
364
365 init_completion(&csid_hw->csid_top_complete);
366
367 /* Save interrupt mask registers values*/
368 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
369 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
370
371 if (csid_reg->cmn_reg->no_pix)
372 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
373 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
374
375 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
376 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
377 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
378 }
379
380 /* Mask all interrupts */
381 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
382 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
383
384 if (csid_reg->cmn_reg->no_pix)
385 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
386 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
387
388 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
389 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
390 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
391
392 /* clear all interrupts */
393 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
394 csid_reg->cmn_reg->csid_top_irq_clear_addr);
395
396 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
397 soc_info->reg_map[0].mem_base +
398 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
399
400 if (csid_reg->cmn_reg->no_pix)
401 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
402 soc_info->reg_map[0].mem_base +
403 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
404
405 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
406 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
407 soc_info->reg_map[0].mem_base +
408 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
409
410 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
411 csid_reg->cmn_reg->csid_irq_cmd_addr);
412
413 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
414 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
415
416 /* enable the IPP and RDI format measure */
417 if (csid_reg->cmn_reg->no_pix)
418 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
419 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
420
421 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
422 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
423 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
424
425 /* perform the top CSID HW reset */
426 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
427 soc_info->reg_map[0].mem_base +
428 csid_reg->cmn_reg->csid_rst_strobes_addr);
429
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700430 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700431 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
432 msecs_to_jiffies(IFE_CSID_TIMEOUT));
433 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700434 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
435 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700436 if (rc == 0)
437 rc = -ETIMEDOUT;
438 } else {
439 rc = 0;
440 }
441
442 /*restore all interrupt masks */
443 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
444 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
445
446 if (csid_reg->cmn_reg->no_pix)
447 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
448 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
449
450 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
451 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
452 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
453
454 return rc;
455}
456
457static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
458 struct cam_csid_reset_cfg_args *reset)
459{
460 int rc = 0;
461 struct cam_hw_soc_info *soc_info;
462 struct cam_isp_resource_node *res;
463 struct cam_ife_csid_reg_offset *csid_reg;
464 uint32_t reset_strb_addr, reset_strb_val, val, id;
465 struct completion *complete;
466
467 csid_reg = csid_hw->csid_info->csid_reg;
468 soc_info = &csid_hw->hw_info->soc_info;
469 res = reset->node_res;
470
471 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700472 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
473 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700474 csid_hw->hw_info->hw_state);
475 return -EINVAL;
476 }
477
478 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700479 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
480 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700481 rc = -EINVAL;
482 goto end;
483 }
484
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700485 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700486 csid_hw->hw_intf->hw_idx, res->res_id);
487
488 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
489 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700490 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
491 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700492 res->res_id);
493 return -EINVAL;
494 }
495
496 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
497 complete = &csid_hw->csid_ipp_complete;
498
499 /* Enable path reset done interrupt */
500 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
501 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
502 val |= CSID_PATH_INFO_RST_DONE;
503 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
504 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
505
506 } else {
507 id = res->res_id;
508 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700509 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
510 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700511 res->res_id);
512 return -EINVAL;
513 }
514
515 reset_strb_addr =
516 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
517 complete =
518 &csid_hw->csid_rdin_complete[id];
519
520 /* Enable path reset done interrupt */
521 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
522 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
523 val |= CSID_PATH_INFO_RST_DONE;
524 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
525 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
526 }
527
528 init_completion(complete);
529 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
530
531 /* Enable the Test gen before reset */
532 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
533 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
534
535 /* Reset the corresponding ife csid path */
536 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
537 reset_strb_addr);
538
539 rc = wait_for_completion_timeout(complete,
540 msecs_to_jiffies(IFE_CSID_TIMEOUT));
541 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700542 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
543 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700544 res->res_id, rc);
545 if (rc == 0)
546 rc = -ETIMEDOUT;
547 }
548
549 /* Disable Test Gen after reset*/
550 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
551 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
552
553end:
554 return rc;
555
556}
557
558static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
559 struct cam_csid_hw_reserve_resource_args *cid_reserv)
560{
561 int rc = 0;
562 struct cam_ife_csid_cid_data *cid_data;
563
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700564 CAM_DBG(CAM_ISP,
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530565 "CSID:%d res_sel:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700566 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700567 cid_reserv->in_port->res_type,
568 cid_reserv->in_port->lane_type,
569 cid_reserv->in_port->lane_num,
570 cid_reserv->in_port->dt,
571 cid_reserv->in_port->vc);
572
573 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700574 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
575 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700576 cid_reserv->in_port->res_type);
577 rc = -EINVAL;
578 goto end;
579 }
580
581 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
582 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700583 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
584 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700585 cid_reserv->in_port->lane_type);
586 rc = -EINVAL;
587 goto end;
588 }
589
590 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
591 cid_reserv->in_port->lane_num > 4) &&
592 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700593 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
594 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700595 cid_reserv->in_port->lane_num);
596 rc = -EINVAL;
597 goto end;
598 }
599 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
600 cid_reserv->in_port->lane_num > 3) &&
601 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700602 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
603 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700604 cid_reserv->in_port->lane_type,
605 cid_reserv->in_port->lane_num);
606 rc = -EINVAL;
607 goto end;
608 }
609
610 /* CSID CSI2 v2.0 supports 31 vc */
611 if (cid_reserv->in_port->dt > 0x3f ||
612 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700613 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
614 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700615 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
616 rc = -EINVAL;
617 goto end;
618 }
619
620 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
621 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
622 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700623 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
624 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700625 cid_reserv->in_port->format);
626 rc = -EINVAL;
627 goto end;
628 }
629
630 if (csid_hw->csi2_reserve_cnt) {
631 /* current configure res type should match requested res type */
632 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
633 rc = -EINVAL;
634 goto end;
635 }
636
637 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
638 if (csid_hw->csi2_rx_cfg.lane_cfg !=
639 cid_reserv->in_port->lane_cfg ||
640 csid_hw->csi2_rx_cfg.lane_type !=
641 cid_reserv->in_port->lane_type ||
642 csid_hw->csi2_rx_cfg.lane_num !=
643 cid_reserv->in_port->lane_num) {
644 rc = -EINVAL;
645 goto end;
646 }
647 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700648 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700649 cid_reserv->in_port->format ||
650 csid_hw->tpg_cfg.width !=
651 cid_reserv->in_port->left_width ||
652 csid_hw->tpg_cfg.height !=
653 cid_reserv->in_port->height ||
654 csid_hw->tpg_cfg.test_pattern !=
655 cid_reserv->in_port->test_pattern) {
656 rc = -EINVAL;
657 goto end;
658 }
659 }
660 }
661
662 if (!csid_hw->csi2_reserve_cnt) {
663 csid_hw->res_type = cid_reserv->in_port->res_type;
664 /* Take the first CID resource*/
665 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
666 cid_data = (struct cam_ife_csid_cid_data *)
667 csid_hw->cid_res[0].res_priv;
668
669 csid_hw->csi2_rx_cfg.lane_cfg =
670 cid_reserv->in_port->lane_cfg;
671 csid_hw->csi2_rx_cfg.lane_type =
672 cid_reserv->in_port->lane_type;
673 csid_hw->csi2_rx_cfg.lane_num =
674 cid_reserv->in_port->lane_num;
675
676 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
677 csid_hw->csi2_rx_cfg.phy_sel = 0;
678 if (cid_reserv->in_port->format >
679 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700680 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700681 rc = -EINVAL;
682 goto end;
683 }
Harsh Shahf7136392017-08-29 12:42:52 -0700684 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700685 cid_reserv->in_port->format;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530686 csid_hw->tpg_cfg.usage_type =
687 cid_reserv->in_port->usage_type;
688 if (cid_reserv->in_port->usage_type)
689 csid_hw->tpg_cfg.width =
690 (cid_reserv->in_port->right_stop + 1);
691 else
692 csid_hw->tpg_cfg.width =
693 cid_reserv->in_port->left_width;
694
Jing Zhouff57d862017-03-21 00:54:25 -0700695 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
696 csid_hw->tpg_cfg.test_pattern =
697 cid_reserv->in_port->test_pattern;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530698
699 CAM_DBG(CAM_ISP, "CSID:%d TPG width:%d height:%d",
700 csid_hw->hw_intf->hw_idx,
701 csid_hw->tpg_cfg.width,
702 csid_hw->tpg_cfg.height);
703
Jing Zhouff57d862017-03-21 00:54:25 -0700704 cid_data->tpg_set = 1;
705 } else {
706 csid_hw->csi2_rx_cfg.phy_sel =
707 (cid_reserv->in_port->res_type & 0xFF) - 1;
708 }
709
710 cid_data->vc = cid_reserv->in_port->vc;
711 cid_data->dt = cid_reserv->in_port->dt;
712 cid_data->cnt = 1;
713 cid_reserv->node_res = &csid_hw->cid_res[0];
714 csid_hw->csi2_reserve_cnt++;
715
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700716 CAM_DBG(CAM_ISP,
717 "CSID:%d CID :%d resource acquired successfully",
718 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700719 cid_reserv->node_res->res_id);
720 } else {
721 rc = cam_ife_csid_cid_get(csid_hw, &cid_reserv->node_res,
722 cid_reserv->in_port->vc, cid_reserv->in_port->dt,
723 cid_reserv->in_port->res_type);
724 /* if success then increment the reserve count */
725 if (!rc) {
726 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700727 CAM_ERR(CAM_ISP,
728 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700729 csid_hw->hw_intf->hw_idx);
730 rc = -EINVAL;
731 } else {
732 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700733 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700734 csid_hw->hw_intf->hw_idx,
735 cid_reserv->node_res->res_id);
736 }
737 }
738 }
739
740end:
741 return rc;
742}
743
744
745static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
746 struct cam_csid_hw_reserve_resource_args *reserve)
747{
748 int rc = 0;
749 struct cam_ife_csid_path_cfg *path_data;
750 struct cam_isp_resource_node *res;
751
752 /* CSID CSI2 v2.0 supports 31 vc */
753 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
754 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700755 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
756 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700757 reserve->in_port->vc, reserve->in_port->dt,
758 reserve->sync_mode);
759 rc = -EINVAL;
760 goto end;
761 }
762
763 switch (reserve->res_id) {
764 case CAM_IFE_PIX_PATH_RES_IPP:
765 if (csid_hw->ipp_res.res_state !=
766 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700767 CAM_DBG(CAM_ISP,
768 "CSID:%d IPP resource not available %d",
769 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700770 csid_hw->ipp_res.res_state);
771 rc = -EINVAL;
772 goto end;
773 }
774
775 if (cam_ife_csid_is_ipp_format_supported(
776 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700777 CAM_ERR(CAM_ISP,
778 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700779 csid_hw->hw_intf->hw_idx, reserve->res_id,
780 reserve->in_port->format);
781 rc = -EINVAL;
782 goto end;
783 }
784
785 /* assign the IPP resource */
786 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700787 CAM_DBG(CAM_ISP,
788 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700789 csid_hw->hw_intf->hw_idx, res->res_id);
790
791 break;
792 case CAM_IFE_PIX_PATH_RES_RDI_0:
793 case CAM_IFE_PIX_PATH_RES_RDI_1:
794 case CAM_IFE_PIX_PATH_RES_RDI_2:
795 case CAM_IFE_PIX_PATH_RES_RDI_3:
796 if (csid_hw->rdi_res[reserve->res_id].res_state !=
797 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700798 CAM_DBG(CAM_ISP,
799 "CSID:%d RDI:%d resource not available %d",
800 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700801 reserve->res_id,
802 csid_hw->rdi_res[reserve->res_id].res_state);
803 rc = -EINVAL;
804 goto end;
805 } else {
806 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700807 CAM_DBG(CAM_ISP,
808 "CSID:%d RDI resource:%d acquire success",
809 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700810 res->res_id);
811 }
812
813 break;
814 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700815 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700816 csid_hw->hw_intf->hw_idx, reserve->res_id);
817 rc = -EINVAL;
818 goto end;
819 }
820
821 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
822 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
823
824 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700825 path_data->in_format = reserve->in_port->format;
826 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700827 path_data->master_idx = reserve->master_idx;
828 path_data->sync_mode = reserve->sync_mode;
829 path_data->height = reserve->in_port->height;
830 path_data->start_line = reserve->in_port->line_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530831 path_data->end_line = reserve->in_port->line_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700832 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
833 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
834 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
835 } else {
836 path_data->dt = reserve->in_port->dt;
837 path_data->vc = reserve->in_port->vc;
838 }
839
840 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
841 path_data->crop_enable = 1;
842 path_data->start_pixel = reserve->in_port->left_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530843 path_data->end_pixel = reserve->in_port->left_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700844 path_data->width = reserve->in_port->left_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530845 CAM_DBG(CAM_ISP, "CSID:%dmaster:startpixel 0x%x endpixel:0x%x",
846 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
847 path_data->end_pixel);
848 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
849 csid_hw->hw_intf->hw_idx, path_data->start_line,
850 path_data->end_line);
Jing Zhouff57d862017-03-21 00:54:25 -0700851 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
852 path_data->crop_enable = 1;
853 path_data->start_pixel = reserve->in_port->right_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530854 path_data->end_pixel = reserve->in_port->right_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700855 path_data->width = reserve->in_port->right_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530856 CAM_DBG(CAM_ISP, "CSID:%d slave:start:0x%x end:0x%x width 0x%x",
857 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
858 path_data->end_pixel, path_data->width);
859 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
860 csid_hw->hw_intf->hw_idx, path_data->start_line,
861 path_data->end_line);
Harsh Shahf7136392017-08-29 12:42:52 -0700862 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700863 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700864 path_data->width = reserve->in_port->left_width;
865 path_data->start_pixel = reserve->in_port->left_start;
866 }
Jing Zhouff57d862017-03-21 00:54:25 -0700867
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530868 CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
Harsh Shahf7136392017-08-29 12:42:52 -0700869 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700870 reserve->node_res = res;
871
872end:
873 return rc;
874}
875
876static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
877{
878 int rc = 0;
879 struct cam_ife_csid_reg_offset *csid_reg;
880 struct cam_hw_soc_info *soc_info;
881 uint32_t i, status, val;
882
883 csid_reg = csid_hw->csid_info->csid_reg;
884 soc_info = &csid_hw->hw_info->soc_info;
885
886 /* overflow check before increment */
887 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700888 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
889 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700890 return -EINVAL;
891 }
892
893 /* Increment ref Count */
894 csid_hw->hw_info->open_count++;
895 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700896 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700897 return rc;
898 }
899
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700900 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700901 csid_hw->hw_intf->hw_idx);
902
903 rc = cam_ife_csid_enable_soc_resources(soc_info);
904 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700905 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700906 csid_hw->hw_intf->hw_idx);
907 goto err;
908 }
909
910
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700911 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700912 csid_hw->hw_intf->hw_idx);
913
914 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
915 /* Enable the top IRQ interrupt */
916 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
917 csid_reg->cmn_reg->csid_top_irq_mask_addr);
918
919 rc = cam_ife_csid_global_reset(csid_hw);
920 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700921 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
922 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700923 rc = -ETIMEDOUT;
924 goto disable_soc;
925 }
926
927 /*
928 * Reset the SW registers
929 * SW register reset also reset the mask irq, so poll the irq status
930 * to check the reset complete.
931 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700932 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700933 csid_hw->hw_intf->hw_idx);
934
935 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
936 soc_info->reg_map[0].mem_base +
937 csid_reg->cmn_reg->csid_rst_strobes_addr);
938
939 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
940 csid_reg->cmn_reg->csid_top_irq_status_addr,
941 status, (status & 0x1) == 0x1,
942 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
943 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700944 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700945 rc = -ETIMEDOUT;
946 goto disable_soc;
947 }
948
949 /* clear all interrupts */
950 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
951 csid_reg->cmn_reg->csid_top_irq_clear_addr);
952
953 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
954 soc_info->reg_map[0].mem_base +
955 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
956
957 if (csid_reg->cmn_reg->no_pix)
958 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
959 soc_info->reg_map[0].mem_base +
960 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
961
962 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
963 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
964 soc_info->reg_map[0].mem_base +
965 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
966
967 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
968 csid_reg->cmn_reg->csid_irq_cmd_addr);
969
970 /* Enable the top IRQ interrupt */
971 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
972 csid_reg->cmn_reg->csid_top_irq_mask_addr);
973
974 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
975 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700976 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -0700977 csid_hw->hw_intf->hw_idx, val);
978
979 return 0;
980
981disable_soc:
982 cam_ife_csid_disable_soc_resources(soc_info);
983 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
984err:
985 csid_hw->hw_info->open_count--;
986 return rc;
987}
988
989static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
990{
991 int rc = 0;
992 struct cam_hw_soc_info *soc_info;
993 struct cam_ife_csid_reg_offset *csid_reg;
994
995
996 /* Decrement ref Count */
997 if (csid_hw->hw_info->open_count)
998 csid_hw->hw_info->open_count--;
999 if (csid_hw->hw_info->open_count)
1000 return rc;
1001
1002 soc_info = &csid_hw->hw_info->soc_info;
1003 csid_reg = csid_hw->csid_info->csid_reg;
1004
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001005 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -07001006 csid_hw->hw_intf->hw_idx);
1007
1008 /*disable the top IRQ interrupt */
1009 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1010 csid_reg->cmn_reg->csid_top_irq_mask_addr);
1011
1012 rc = cam_ife_csid_disable_soc_resources(soc_info);
1013 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001014 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
1015 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001016
1017 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
1018 return rc;
1019}
1020
1021
1022static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
1023 struct cam_isp_resource_node *res)
1024{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301025 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001026 uint32_t val = 0;
1027 struct cam_hw_soc_info *soc_info;
1028
1029 csid_hw->tpg_start_cnt++;
1030 if (csid_hw->tpg_start_cnt == 1) {
1031 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001032 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1033 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001034
1035 soc_info = &csid_hw->hw_info->soc_info;
1036 {
1037 uint32_t val;
1038 uint32_t i;
1039 uint32_t base = 0x600;
1040
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001041 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001042 for (i = 0; i < 16; i++) {
1043 val = cam_io_r_mb(
1044 soc_info->reg_map[0].mem_base +
1045 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001046 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001047 (base + i*4), val);
1048 }
1049
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001050 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001051 base = 0x200;
1052 for (i = 0; i < 10; i++) {
1053 val = cam_io_r_mb(
1054 soc_info->reg_map[0].mem_base +
1055 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001056 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001057 (base + i*4), val);
1058 }
1059
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001060 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001061 base = 0x100;
1062 for (i = 0; i < 5; i++) {
1063 val = cam_io_r_mb(
1064 soc_info->reg_map[0].mem_base +
1065 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001066 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001067 (base + i*4), val);
1068 }
1069 }
1070
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301071 /* Enable the IFE force clock on for dual isp case */
1072 if (csid_hw->tpg_cfg.usage_type) {
1073 rc = cam_ife_csid_enable_ife_force_clock_on(soc_info,
1074 csid_hw->csid_info->csid_reg->tpg_reg->
1075 tpg_cpas_ife_reg_offset);
1076 if (rc)
1077 return rc;
1078 }
1079
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001080 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001081 val = (4 << 20);
1082 val |= (0x80 << 8);
1083 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1084 val |= 7;
1085 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1086 csid_hw->csid_info->csid_reg->tpg_reg->
1087 csid_tpg_ctrl_addr);
1088
1089 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001090 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001091 }
1092
1093 return 0;
1094}
1095
1096static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1097 struct cam_isp_resource_node *res)
1098{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301099 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001100 struct cam_hw_soc_info *soc_info;
1101
1102 if (csid_hw->tpg_start_cnt)
1103 csid_hw->tpg_start_cnt--;
1104
1105 if (csid_hw->tpg_start_cnt)
1106 return 0;
1107
1108 soc_info = &csid_hw->hw_info->soc_info;
1109
1110 /* disable the TPG */
1111 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001112 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1113 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001114
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301115 /* Disable the IFE force clock on for dual isp case */
1116 if (csid_hw->tpg_cfg.usage_type)
1117 rc = cam_ife_csid_disable_ife_force_clock_on(soc_info,
1118 csid_hw->csid_info->csid_reg->tpg_reg->
1119 tpg_cpas_ife_reg_offset);
1120
Jing Zhouff57d862017-03-21 00:54:25 -07001121 /*stop the TPG */
1122 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1123 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1124 }
1125
1126 return 0;
1127}
1128
1129
1130static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1131 struct cam_isp_resource_node *res)
1132{
1133 struct cam_ife_csid_reg_offset *csid_reg;
1134 struct cam_hw_soc_info *soc_info;
1135 uint32_t val = 0;
1136
1137 csid_reg = csid_hw->csid_info->csid_reg;
1138 soc_info = &csid_hw->hw_info->soc_info;
1139
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001140 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1141 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001142
1143 /* configure one DT, infinite frames */
1144 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1145 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1146 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1147
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301148 /* vertical blanking count = 0x3FF, horzontal blanking count = 0x740*/
1149 val = (0x3FF << 12) | 0x740;
Jing Zhouff57d862017-03-21 00:54:25 -07001150 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1151 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1152
1153 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1154 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1155
1156 val = csid_hw->tpg_cfg.width << 16 |
1157 csid_hw->tpg_cfg.height;
1158 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1159 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1160
1161 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1162 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1163
1164 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001165 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001166 * it is one larger than the register spec format.
1167 */
Harsh Shahf7136392017-08-29 12:42:52 -07001168 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001169 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1170 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1171
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001172 /* static frame with split color bar */
1173 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001174 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1175 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1176 /* config pix pattern */
1177 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1178 soc_info->reg_map[0].mem_base +
1179 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1180
1181 return 0;
1182}
1183
1184static int cam_ife_csid_enable_csi2(
1185 struct cam_ife_csid_hw *csid_hw,
1186 struct cam_isp_resource_node *res)
1187{
1188 int rc = 0;
1189 struct cam_ife_csid_reg_offset *csid_reg;
1190 struct cam_hw_soc_info *soc_info;
1191 struct cam_ife_csid_cid_data *cid_data;
1192 uint32_t val = 0;
1193
1194 csid_reg = csid_hw->csid_info->csid_reg;
1195 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001196 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1197 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001198
1199 /* overflow check before increment */
1200 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001201 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1202 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001203 return -EINVAL;
1204 }
1205
1206 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1207
1208 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1209 csid_hw->csi2_cfg_cnt++;
1210 if (csid_hw->csi2_cfg_cnt > 1)
1211 return rc;
1212
1213 /* rx cfg0 */
1214 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1215 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1216 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001217 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001218 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1219 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1220
1221 /* rx cfg1*/
1222 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1223 /* if VC value is more than 3 than set full width of VC */
1224 if (cid_data->vc > 3)
1225 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1226
1227 /* enable packet ecc correction */
1228 val |= 1;
1229 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1230 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1231
1232 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1233 /* Config the TPG */
1234 rc = cam_ife_csid_config_tpg(csid_hw, res);
1235 if (rc) {
1236 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1237 return rc;
1238 }
1239 }
1240
1241 /*Enable the CSI2 rx inerrupts */
1242 val = CSID_CSI2_RX_INFO_RST_DONE |
1243 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1244 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1245 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1246 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1247 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1248 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1249 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
1250 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301251
1252 /* Enable the interrupt based on csid debug info set */
1253 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ)
1254 val |= CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED |
1255 CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED |
1256 CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED |
1257 CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED;
1258
1259 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ)
1260 val |= CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED |
1261 CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED |
1262 CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED |
1263 CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED;
1264
1265 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1266 val |= CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED;
1267
1268 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1269 val |= CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED;
1270 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1271 val |= CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED;
1272
Jing Zhouff57d862017-03-21 00:54:25 -07001273 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1274 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1275
1276 return 0;
1277}
1278
1279static int cam_ife_csid_disable_csi2(
1280 struct cam_ife_csid_hw *csid_hw,
1281 struct cam_isp_resource_node *res)
1282{
1283 struct cam_ife_csid_reg_offset *csid_reg;
1284 struct cam_hw_soc_info *soc_info;
1285
1286 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001287 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1288 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001289 return -EINVAL;
1290 }
1291
1292 csid_reg = csid_hw->csid_info->csid_reg;
1293 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001294 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1295 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001296
1297 if (csid_hw->csi2_cfg_cnt)
1298 csid_hw->csi2_cfg_cnt--;
1299
1300 if (csid_hw->csi2_cfg_cnt)
1301 return 0;
1302
1303 /*Disable the CSI2 rx inerrupts */
1304 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1305 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1306
1307 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1308
1309 return 0;
1310}
1311
1312static int cam_ife_csid_init_config_ipp_path(
1313 struct cam_ife_csid_hw *csid_hw,
1314 struct cam_isp_resource_node *res)
1315{
1316 int rc = 0;
1317 struct cam_ife_csid_path_cfg *path_data;
1318 struct cam_ife_csid_reg_offset *csid_reg;
1319 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001320 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001321
1322 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1323 csid_reg = csid_hw->csid_info->csid_reg;
1324 soc_info = &csid_hw->hw_info->soc_info;
1325
1326 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001327 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1328 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001329 res->res_id);
1330 return -EINVAL;
1331 }
1332
Harsh Shahf7136392017-08-29 12:42:52 -07001333 CAM_DBG(CAM_ISP, "Config IPP Path");
1334 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1335 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001336 if (rc)
1337 return rc;
1338
Jing Zhoubb536a82017-05-18 15:20:38 -07001339 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001340 * configure the IPP and enable the time stamp capture.
1341 * enable the HW measrurement blocks
1342 */
1343 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1344 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1345 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001346 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301347 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001348 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301349 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001350 csid_reg->cmn_reg->crop_v_en_shift_val) |
1351 (1 << 1) | 1;
1352 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1353 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1354 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1355
Jing Zhoudedc4762017-06-19 17:45:36 +05301356 /* select the post irq sub sample strobe for time stamp capture */
1357 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1358 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1359
Jing Zhouff57d862017-03-21 00:54:25 -07001360 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301361 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001362 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301363 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001364 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1365 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301366 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1367 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001368
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301369 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001370 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301371 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001372 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1373 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301374 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1375 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001376 }
1377
1378 /* set frame drop pattern to 0 and period to 1 */
1379 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1380 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1381 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1382 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1383 /* set irq sub sample pattern to 0 and period to 1 */
1384 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1385 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1386 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1387 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1388 /* set pixel drop pattern to 0 and period to 1 */
1389 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1390 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1391 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1392 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1393 /* set line drop pattern to 0 and period to 1 */
1394 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1395 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1396 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1397 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1398
1399 /*Set master or slave IPP */
1400 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1401 /*Set halt mode as master */
1402 val = CSID_HALT_MODE_MASTER << 2;
1403 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1404 /*Set halt mode as slave and set master idx */
1405 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1406 else
1407 /* Default is internal halt mode */
1408 val = 0;
1409
1410 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1411 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1412
1413 /* Enable the IPP path */
1414 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1415 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1416 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1417 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1418 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1419
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301420 /* configure the rx packet capture based on csid debug set */
1421 val = 0;
1422 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1423 val = ((1 <<
1424 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1425 (path_data->vc <<
1426 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1427
1428 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1429 val |= ((1 <<
1430 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1431 (path_data->dt <<
1432 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1433 (path_data->vc <<
1434 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1435
1436 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1437 val |= ((1 <<
1438 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1439 (path_data->dt <<
1440 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1441 (path_data->vc <<
1442 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1443
1444 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1445 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1446 CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val);
1447
Jing Zhouff57d862017-03-21 00:54:25 -07001448 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1449
1450 return rc;
1451}
1452
1453static int cam_ife_csid_deinit_ipp_path(
1454 struct cam_ife_csid_hw *csid_hw,
1455 struct cam_isp_resource_node *res)
1456{
1457 int rc = 0;
1458 struct cam_ife_csid_reg_offset *csid_reg;
1459 struct cam_hw_soc_info *soc_info;
1460 uint32_t val = 0;
1461
1462 csid_reg = csid_hw->csid_info->csid_reg;
1463 soc_info = &csid_hw->hw_info->soc_info;
1464
1465 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001466 CAM_ERR(CAM_ISP,
1467 "CSID:%d Res type %d res_id:%d in wrong state %d",
1468 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001469 res->res_type, res->res_id, res->res_state);
1470 rc = -EINVAL;
1471 }
1472
1473 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001474 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1475 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001476 res->res_id);
1477 rc = -EINVAL;
1478 }
1479
1480 /* Disable the IPP path */
1481 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1482 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1483 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1484 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1485 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1486
1487 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1488 return rc;
1489}
1490
1491static int cam_ife_csid_enable_ipp_path(
1492 struct cam_ife_csid_hw *csid_hw,
1493 struct cam_isp_resource_node *res)
1494{
1495 struct cam_ife_csid_reg_offset *csid_reg;
1496 struct cam_hw_soc_info *soc_info;
1497 struct cam_ife_csid_path_cfg *path_data;
1498 uint32_t val = 0;
1499
1500 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1501 csid_reg = csid_hw->csid_info->csid_reg;
1502 soc_info = &csid_hw->hw_info->soc_info;
1503
1504 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001505 CAM_ERR(CAM_ISP,
1506 "CSID:%d res type:%d res_id:%d Invalid state%d",
1507 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001508 res->res_type, res->res_id, res->res_state);
1509 return -EINVAL;
1510 }
1511
1512 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001513 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1514 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001515 res->res_id);
1516 return -EINVAL;
1517 }
1518
Harsh Shahf7136392017-08-29 12:42:52 -07001519 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001520
Harsh Shahf7136392017-08-29 12:42:52 -07001521 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001522 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1523 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1524 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1525 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1526 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1527 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1528 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1529 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1530 soc_info->reg_map[0].mem_base +
1531 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1532 }
1533 /* for slave mode, not need to resume for slave device */
1534
1535 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301536 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301537
1538 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1539 val |= CSID_PATH_INFO_INPUT_SOF;
1540 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1541 val |= CSID_PATH_INFO_INPUT_EOF;
1542
Jing Zhouff57d862017-03-21 00:54:25 -07001543 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1544 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1545
1546 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1547
1548 return 0;
1549}
1550
1551static int cam_ife_csid_disable_ipp_path(
1552 struct cam_ife_csid_hw *csid_hw,
1553 struct cam_isp_resource_node *res,
1554 enum cam_ife_csid_halt_cmd stop_cmd)
1555{
1556 int rc = 0;
1557 struct cam_ife_csid_reg_offset *csid_reg;
1558 struct cam_hw_soc_info *soc_info;
1559 struct cam_ife_csid_path_cfg *path_data;
1560 uint32_t val = 0;
1561
1562 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1563 csid_reg = csid_hw->csid_info->csid_reg;
1564 soc_info = &csid_hw->hw_info->soc_info;
1565
1566 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001567 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1568 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001569 return -EINVAL;
1570 }
1571
1572 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1573 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001574 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1575 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001576 res->res_id, res->res_state);
1577 return rc;
1578 }
1579
1580 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001581 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1582 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001583 res->res_state);
1584 return -EINVAL;
1585 }
1586
1587 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001588 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1589 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001590 return -EINVAL;
1591 }
1592
1593 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1594 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001595 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1596 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001597 return -EINVAL;
1598 }
1599
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001600 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001601 csid_hw->hw_intf->hw_idx, res->res_id);
1602
1603 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1604 /* configure Halt */
1605 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1606 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1607 val &= ~0x3;
1608 val |= stop_cmd;
1609 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1610 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1611 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1612 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1613 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1614
1615 /* For slave mode, halt command should take it from master */
1616
1617 /* Enable the EOF interrupt for resume at boundary case */
1618 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1619 init_completion(&csid_hw->csid_ipp_complete);
1620 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1621 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1622 val |= CSID_PATH_INFO_INPUT_EOF;
1623 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1624 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1625 } else {
1626 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001627 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001628 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1629 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1630 }
1631
1632 return rc;
1633}
1634
1635
1636static int cam_ife_csid_init_config_rdi_path(
1637 struct cam_ife_csid_hw *csid_hw,
1638 struct cam_isp_resource_node *res)
1639{
1640 int rc = 0;
1641 struct cam_ife_csid_path_cfg *path_data;
1642 struct cam_ife_csid_reg_offset *csid_reg;
1643 struct cam_hw_soc_info *soc_info;
1644 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1645
1646 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1647 csid_reg = csid_hw->csid_info->csid_reg;
1648 soc_info = &csid_hw->hw_info->soc_info;
1649
1650 id = res->res_id;
1651 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001652 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1653 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001654 return -EINVAL;
1655 }
1656
Harsh Shahf7136392017-08-29 12:42:52 -07001657 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1658 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001659 if (rc)
1660 return rc;
1661
Jing Zhoubb536a82017-05-18 15:20:38 -07001662 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001663 * RDI path config and enable the time stamp capture
1664 * Enable the measurement blocks
1665 */
1666 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1667 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1668 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1669 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1670 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301671 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001672 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301673 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001674 csid_reg->cmn_reg->crop_v_en_shift_val) |
1675 (1 << 2) | 3;
1676
1677 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1678 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1679
Jing Zhoudedc4762017-06-19 17:45:36 +05301680 /* select the post irq sub sample strobe for time stamp capture */
1681 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1682 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1683
Jing Zhouff57d862017-03-21 00:54:25 -07001684 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301685 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001686 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301687 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001688
1689 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1690 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301691 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1692 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001693
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301694 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001695 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301696 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001697
1698 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1699 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301700 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1701 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001702 }
1703 /* set frame drop pattern to 0 and period to 1 */
1704 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1705 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1706 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1707 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1708 /* set IRQ sum sabmple */
1709 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1710 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1711 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1712 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1713
1714 /* set pixel drop pattern to 0 and period to 1 */
1715 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1716 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1717 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1718 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1719 /* set line drop pattern to 0 and period to 1 */
1720 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1721 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1722 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1723 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1724
1725 /* Configure the halt mode */
1726 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1727 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1728
1729 /* Enable the RPP path */
1730 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1731 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1732 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001733
Jing Zhouff57d862017-03-21 00:54:25 -07001734 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1735 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1736
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301737 /* configure the rx packet capture based on csid debug set */
1738 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1739 val = ((1 <<
1740 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1741 (path_data->vc <<
1742 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1743
1744 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1745 val |= ((1 <<
1746 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1747 (path_data->dt <<
1748 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1749 (path_data->vc <<
1750 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1751
1752 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1753 val |= ((1 <<
1754 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1755 (path_data->dt <<
1756 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1757 (path_data->vc <<
1758 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1759 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1760 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1761
Jing Zhouff57d862017-03-21 00:54:25 -07001762 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1763
1764 return rc;
1765}
1766
1767static int cam_ife_csid_deinit_rdi_path(
1768 struct cam_ife_csid_hw *csid_hw,
1769 struct cam_isp_resource_node *res)
1770{
1771 int rc = 0;
1772 struct cam_ife_csid_reg_offset *csid_reg;
1773 struct cam_hw_soc_info *soc_info;
1774 uint32_t val = 0, id;
1775
1776 csid_reg = csid_hw->csid_info->csid_reg;
1777 soc_info = &csid_hw->hw_info->soc_info;
1778 id = res->res_id;
1779
1780 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1781 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1782 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001783 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1784 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001785 res->res_state);
1786 return -EINVAL;
1787 }
1788
1789 /* Disable the RDI path */
1790 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1791 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1792 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1793 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1794 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1795
1796 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1797 return rc;
1798}
1799
1800static int cam_ife_csid_enable_rdi_path(
1801 struct cam_ife_csid_hw *csid_hw,
1802 struct cam_isp_resource_node *res)
1803{
1804 struct cam_ife_csid_reg_offset *csid_reg;
1805 struct cam_hw_soc_info *soc_info;
1806 uint32_t id, val;
1807
1808 csid_reg = csid_hw->csid_info->csid_reg;
1809 soc_info = &csid_hw->hw_info->soc_info;
1810 id = res->res_id;
1811
1812 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1813 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1814 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001815 CAM_ERR(CAM_ISP,
1816 "CSID:%d invalid res type:%d res_id:%d state%d",
1817 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001818 res->res_type, res->res_id, res->res_state);
1819 return -EINVAL;
1820 }
1821
1822 /*resume at frame boundary */
1823 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1824 soc_info->reg_map[0].mem_base +
1825 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1826
1827 /* Enable the required RDI interrupts */
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301828 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
1829
1830 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1831 val |= CSID_PATH_INFO_INPUT_SOF;
1832 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1833 val |= CSID_PATH_INFO_INPUT_EOF;
1834
Jing Zhouff57d862017-03-21 00:54:25 -07001835 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1836 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1837
1838 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1839
1840 return 0;
1841}
1842
1843
1844static int cam_ife_csid_disable_rdi_path(
1845 struct cam_ife_csid_hw *csid_hw,
1846 struct cam_isp_resource_node *res,
1847 enum cam_ife_csid_halt_cmd stop_cmd)
1848{
1849 int rc = 0;
1850 struct cam_ife_csid_reg_offset *csid_reg;
1851 struct cam_hw_soc_info *soc_info;
1852 uint32_t val = 0, id;
1853
1854 csid_reg = csid_hw->csid_info->csid_reg;
1855 soc_info = &csid_hw->hw_info->soc_info;
1856 id = res->res_id;
1857
1858 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1859 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001860 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1861 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001862 return -EINVAL;
1863 }
1864
1865 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1866 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001867 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1868 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001869 res->res_id, res->res_state);
1870 return rc;
1871 }
1872
1873 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001874 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1875 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001876 res->res_state);
1877 return -EINVAL;
1878 }
1879
1880 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1881 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001882 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1883 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001884 return -EINVAL;
1885 }
1886
1887
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001888 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001889 csid_hw->hw_intf->hw_idx, res->res_id);
1890
1891 init_completion(&csid_hw->csid_rdin_complete[id]);
1892
1893 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1894 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1895 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1896 val |= CSID_PATH_INFO_INPUT_EOF;
1897 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1898 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1899 } else {
1900 val &= ~(CSID_PATH_INFO_RST_DONE |
1901 CSID_PATH_ERROR_FIFO_OVERFLOW);
1902 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1903 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1904 }
1905
1906 /*Halt the RDI path */
1907 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1908 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1909
1910 return rc;
1911}
1912
1913static int cam_ife_csid_get_time_stamp(
1914 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1915{
1916 struct cam_csid_get_time_stamp_args *time_stamp;
1917 struct cam_isp_resource_node *res;
1918 struct cam_ife_csid_reg_offset *csid_reg;
1919 struct cam_hw_soc_info *soc_info;
1920 uint32_t time_32, id;
1921
1922 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1923 res = time_stamp->node_res;
1924 csid_reg = csid_hw->csid_info->csid_reg;
1925 soc_info = &csid_hw->hw_info->soc_info;
1926
1927 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1928 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001929 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1930 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001931 res->res_id);
1932 return -EINVAL;
1933 }
1934
1935 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001936 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1937 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001938 csid_hw->hw_info->hw_state);
1939 return -EINVAL;
1940 }
1941
1942 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1943 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1944 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1945 time_stamp->time_stamp_val = time_32;
1946 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1947 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1948 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1949 time_stamp->time_stamp_val |= time_32;
1950 } else {
1951 id = res->res_id;
1952 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1953 csid_reg->rdi_reg[id]->
1954 csid_rdi_timestamp_curr1_sof_addr);
1955 time_stamp->time_stamp_val = time_32;
1956 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1957
1958 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1959 csid_reg->rdi_reg[id]->
1960 csid_rdi_timestamp_curr0_sof_addr);
1961 time_stamp->time_stamp_val |= time_32;
1962 }
1963
1964 return 0;
1965}
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301966
1967static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw,
1968 void *cmd_args)
1969{
1970 uint32_t *csid_debug;
1971
1972 csid_debug = (uint32_t *) cmd_args;
1973 csid_hw->csid_debug = *csid_debug;
1974 CAM_DBG(CAM_ISP, "CSID:%d set csid debug value:%d",
1975 csid_hw->hw_intf->hw_idx, csid_hw->csid_debug);
1976
1977 return 0;
1978}
1979
Jing Zhouff57d862017-03-21 00:54:25 -07001980static int cam_ife_csid_res_wait_for_halt(
1981 struct cam_ife_csid_hw *csid_hw,
1982 struct cam_isp_resource_node *res)
1983{
1984 int rc = 0;
1985 struct cam_ife_csid_reg_offset *csid_reg;
1986 struct cam_hw_soc_info *soc_info;
1987
1988 struct completion *complete;
1989 uint32_t val = 0, id;
1990
1991 csid_reg = csid_hw->csid_info->csid_reg;
1992 soc_info = &csid_hw->hw_info->soc_info;
1993
1994 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001995 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1996 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001997 return -EINVAL;
1998 }
1999
2000 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
2001 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002002 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
2003 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002004 res->res_id, res->res_state);
2005 return rc;
2006 }
2007
2008 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002009 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
2010 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07002011 res->res_state);
2012 return -EINVAL;
2013 }
2014
2015 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2016 complete = &csid_hw->csid_ipp_complete;
2017 else
2018 complete = &csid_hw->csid_rdin_complete[res->res_id];
2019
2020 rc = wait_for_completion_timeout(complete,
2021 msecs_to_jiffies(IFE_CSID_TIMEOUT));
2022 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002023 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
2024 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002025 res->res_id, rc);
2026 if (rc == 0)
2027 /* continue even have timeout */
2028 rc = -ETIMEDOUT;
2029 }
2030
2031 /* Disable the interrupt */
2032 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
2033 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2034 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2035 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2036 CSID_PATH_ERROR_FIFO_OVERFLOW);
2037 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2038 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2039 } else {
2040 id = res->res_id;
2041 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2042 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2043 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2044 CSID_PATH_ERROR_FIFO_OVERFLOW);
2045 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2046 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2047 }
2048 /* set state to init HW */
2049 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
2050 return rc;
2051}
2052
2053static int cam_ife_csid_get_hw_caps(void *hw_priv,
2054 void *get_hw_cap_args, uint32_t arg_size)
2055{
2056 int rc = 0;
2057 struct cam_ife_csid_hw_caps *hw_caps;
2058 struct cam_ife_csid_hw *csid_hw;
2059 struct cam_hw_info *csid_hw_info;
2060 struct cam_ife_csid_reg_offset *csid_reg;
2061
2062 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002063 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002064 return -EINVAL;
2065 }
2066
2067 csid_hw_info = (struct cam_hw_info *)hw_priv;
2068 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2069 csid_reg = csid_hw->csid_info->csid_reg;
2070 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
2071
2072 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
2073 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
2074 hw_caps->major_version = csid_reg->cmn_reg->major_version;
2075 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
2076 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
2077
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002078 CAM_DBG(CAM_ISP,
2079 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
2080 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07002081 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
2082 hw_caps->version_incr);
2083
2084 return rc;
2085}
2086
2087static int cam_ife_csid_reset(void *hw_priv,
2088 void *reset_args, uint32_t arg_size)
2089{
2090 struct cam_ife_csid_hw *csid_hw;
2091 struct cam_hw_info *csid_hw_info;
2092 struct cam_csid_reset_cfg_args *reset;
2093 int rc = 0;
2094
2095 if (!hw_priv || !reset_args || (arg_size !=
2096 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002097 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002098 return -EINVAL;
2099 }
2100
2101 csid_hw_info = (struct cam_hw_info *)hw_priv;
2102 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2103 reset = (struct cam_csid_reset_cfg_args *)reset_args;
2104
2105 switch (reset->reset_type) {
2106 case CAM_IFE_CSID_RESET_GLOBAL:
2107 rc = cam_ife_csid_global_reset(csid_hw);
2108 break;
2109 case CAM_IFE_CSID_RESET_PATH:
2110 rc = cam_ife_csid_path_reset(csid_hw, reset);
2111 break;
2112 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002113 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
2114 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002115 rc = -EINVAL;
2116 break;
2117 }
2118
2119 return rc;
2120}
2121
2122static int cam_ife_csid_reserve(void *hw_priv,
2123 void *reserve_args, uint32_t arg_size)
2124{
2125 int rc = 0;
2126 struct cam_ife_csid_hw *csid_hw;
2127 struct cam_hw_info *csid_hw_info;
2128 struct cam_csid_hw_reserve_resource_args *reserv;
2129
2130 if (!hw_priv || !reserve_args || (arg_size !=
2131 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002132 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002133 return -EINVAL;
2134 }
2135
2136 csid_hw_info = (struct cam_hw_info *)hw_priv;
2137 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2138 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2139
2140 mutex_lock(&csid_hw->hw_info->hw_mutex);
2141 switch (reserv->res_type) {
2142 case CAM_ISP_RESOURCE_CID:
2143 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2144 break;
2145 case CAM_ISP_RESOURCE_PIX_PATH:
2146 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2147 break;
2148 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002149 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2150 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002151 rc = -EINVAL;
2152 break;
2153 }
2154 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2155 return rc;
2156}
2157
2158static int cam_ife_csid_release(void *hw_priv,
2159 void *release_args, uint32_t arg_size)
2160{
2161 int rc = 0;
2162 struct cam_ife_csid_hw *csid_hw;
2163 struct cam_hw_info *csid_hw_info;
2164 struct cam_isp_resource_node *res;
2165 struct cam_ife_csid_cid_data *cid_data;
2166
2167 if (!hw_priv || !release_args ||
2168 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002169 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002170 return -EINVAL;
2171 }
2172
2173 csid_hw_info = (struct cam_hw_info *)hw_priv;
2174 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2175 res = (struct cam_isp_resource_node *)release_args;
2176
2177 mutex_lock(&csid_hw->hw_info->hw_mutex);
2178 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2179 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2180 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2181 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002182 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2183 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002184 res->res_id);
2185 rc = -EINVAL;
2186 goto end;
2187 }
2188
2189 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002190 CAM_DBG(CAM_ISP,
2191 "CSID:%d res type:%d Res %d in released state",
2192 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002193 res->res_type, res->res_id);
2194 goto end;
2195 }
2196
2197 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2198 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002199 CAM_DBG(CAM_ISP,
2200 "CSID:%d res type:%d Res id:%d invalid state:%d",
2201 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002202 res->res_type, res->res_id, res->res_state);
2203 rc = -EINVAL;
2204 goto end;
2205 }
2206
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002207 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2208 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002209
2210 switch (res->res_type) {
2211 case CAM_ISP_RESOURCE_CID:
2212 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2213 if (cid_data->cnt)
2214 cid_data->cnt--;
2215
2216 if (!cid_data->cnt)
2217 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2218
2219 if (csid_hw->csi2_reserve_cnt)
2220 csid_hw->csi2_reserve_cnt--;
2221
2222 if (!csid_hw->csi2_reserve_cnt)
2223 memset(&csid_hw->csi2_rx_cfg, 0,
2224 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2225
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002226 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2227 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002228 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2229
2230 break;
2231 case CAM_ISP_RESOURCE_PIX_PATH:
2232 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2233 break;
2234 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002235 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2236 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002237 res->res_id);
2238 rc = -EINVAL;
2239 break;
2240 }
2241
2242end:
2243 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2244 return rc;
2245}
2246
2247static int cam_ife_csid_init_hw(void *hw_priv,
2248 void *init_args, uint32_t arg_size)
2249{
2250 int rc = 0;
2251 struct cam_ife_csid_hw *csid_hw;
2252 struct cam_hw_info *csid_hw_info;
2253 struct cam_isp_resource_node *res;
2254 struct cam_ife_csid_reg_offset *csid_reg;
2255
2256 if (!hw_priv || !init_args ||
2257 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002258 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002259 return -EINVAL;
2260 }
2261
2262 csid_hw_info = (struct cam_hw_info *)hw_priv;
2263 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2264 res = (struct cam_isp_resource_node *)init_args;
2265 csid_reg = csid_hw->csid_info->csid_reg;
2266
2267 mutex_lock(&csid_hw->hw_info->hw_mutex);
2268 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2269 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2270 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2271 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002272 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2273 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002274 res->res_id);
2275 rc = -EINVAL;
2276 goto end;
2277 }
2278
2279
2280 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2281 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002282 CAM_ERR(CAM_ISP,
2283 "CSID:%d res type:%d res_id:%dInvalid state %d",
2284 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002285 res->res_type, res->res_id, res->res_state);
2286 rc = -EINVAL;
2287 goto end;
2288 }
2289
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002290 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002291 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2292
2293
2294 /* Initialize the csid hardware */
2295 rc = cam_ife_csid_enable_hw(csid_hw);
2296 if (rc)
2297 goto end;
2298
2299 switch (res->res_type) {
2300 case CAM_ISP_RESOURCE_CID:
2301 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2302 break;
2303 case CAM_ISP_RESOURCE_PIX_PATH:
2304 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2305 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2306 else
2307 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2308
2309 break;
2310 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002311 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2312 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002313 res->res_type);
2314 break;
2315 }
2316
2317 if (rc)
2318 cam_ife_csid_disable_hw(csid_hw);
2319end:
2320 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2321 return rc;
2322}
2323
2324static int cam_ife_csid_deinit_hw(void *hw_priv,
2325 void *deinit_args, uint32_t arg_size)
2326{
2327 int rc = 0;
2328 struct cam_ife_csid_hw *csid_hw;
2329 struct cam_hw_info *csid_hw_info;
2330 struct cam_isp_resource_node *res;
2331
2332 if (!hw_priv || !deinit_args ||
2333 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002334 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002335 return -EINVAL;
2336 }
2337
2338 res = (struct cam_isp_resource_node *)deinit_args;
2339 csid_hw_info = (struct cam_hw_info *)hw_priv;
2340 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2341
2342 mutex_lock(&csid_hw->hw_info->hw_mutex);
2343 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002344 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2345 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002346 res->res_id);
2347 goto end;
2348 }
2349
2350 switch (res->res_type) {
2351 case CAM_ISP_RESOURCE_CID:
2352 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2353 break;
2354 case CAM_ISP_RESOURCE_PIX_PATH:
2355 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2356 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2357 else
2358 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2359
2360 break;
2361 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002362 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2363 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002364 res->res_type);
2365 goto end;
2366 }
2367
2368 /* Disable CSID HW */
2369 cam_ife_csid_disable_hw(csid_hw);
2370
2371end:
2372 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2373 return rc;
2374}
2375
2376static int cam_ife_csid_start(void *hw_priv, void *start_args,
2377 uint32_t arg_size)
2378{
2379 int rc = 0;
2380 struct cam_ife_csid_hw *csid_hw;
2381 struct cam_hw_info *csid_hw_info;
2382 struct cam_isp_resource_node *res;
2383 struct cam_ife_csid_reg_offset *csid_reg;
2384
2385 if (!hw_priv || !start_args ||
2386 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002387 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002388 return -EINVAL;
2389 }
2390
2391 csid_hw_info = (struct cam_hw_info *)hw_priv;
2392 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2393 res = (struct cam_isp_resource_node *)start_args;
2394 csid_reg = csid_hw->csid_info->csid_reg;
2395
Jing Zhouff57d862017-03-21 00:54:25 -07002396 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2397 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2398 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2399 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002400 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2401 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002402 res->res_id);
2403 rc = -EINVAL;
2404 goto end;
2405 }
2406
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002407 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002408 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2409
2410 switch (res->res_type) {
2411 case CAM_ISP_RESOURCE_CID:
2412 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2413 rc = cam_ife_csid_tpg_start(csid_hw, res);
2414 break;
2415 case CAM_ISP_RESOURCE_PIX_PATH:
2416 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2417 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2418 else
2419 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2420 break;
2421 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002422 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2423 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002424 res->res_type);
2425 break;
2426 }
2427end:
Jing Zhouff57d862017-03-21 00:54:25 -07002428 return rc;
2429}
2430
2431static int cam_ife_csid_stop(void *hw_priv,
2432 void *stop_args, uint32_t arg_size)
2433{
2434 int rc = 0;
2435 struct cam_ife_csid_hw *csid_hw;
2436 struct cam_hw_info *csid_hw_info;
2437 struct cam_isp_resource_node *res;
2438 struct cam_csid_hw_stop_args *csid_stop;
2439 uint32_t i;
2440
2441 if (!hw_priv || !stop_args ||
2442 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002443 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002444 return -EINVAL;
2445 }
2446 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2447 csid_hw_info = (struct cam_hw_info *)hw_priv;
2448 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2449
Jing Zhouff57d862017-03-21 00:54:25 -07002450 /* Stop the resource first */
2451 for (i = 0; i < csid_stop->num_res; i++) {
2452 res = csid_stop->node_res[i];
2453 switch (res->res_type) {
2454 case CAM_ISP_RESOURCE_CID:
2455 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2456 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2457 break;
2458 case CAM_ISP_RESOURCE_PIX_PATH:
2459 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2460 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2461 res, csid_stop->stop_cmd);
2462 else
2463 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2464 res, csid_stop->stop_cmd);
2465
2466 break;
2467 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002468 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2469 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002470 res->res_type);
2471 break;
2472 }
2473 }
2474
2475 /*wait for the path to halt */
2476 for (i = 0; i < csid_stop->num_res; i++) {
2477 res = csid_stop->node_res[i];
2478 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2479 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2480 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302481 else
2482 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002483 }
2484
Jing Zhouff57d862017-03-21 00:54:25 -07002485 return rc;
2486
2487}
2488
2489static int cam_ife_csid_read(void *hw_priv,
2490 void *read_args, uint32_t arg_size)
2491{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002492 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002493
2494 return -EINVAL;
2495}
2496
2497static int cam_ife_csid_write(void *hw_priv,
2498 void *write_args, uint32_t arg_size)
2499{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002500 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002501 return -EINVAL;
2502}
2503
2504static int cam_ife_csid_process_cmd(void *hw_priv,
2505 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2506{
2507 int rc = 0;
2508 struct cam_ife_csid_hw *csid_hw;
2509 struct cam_hw_info *csid_hw_info;
2510
2511 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002512 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002513 return -EINVAL;
2514 }
2515
2516 csid_hw_info = (struct cam_hw_info *)hw_priv;
2517 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2518
Jing Zhouff57d862017-03-21 00:54:25 -07002519 switch (cmd_type) {
2520 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2521 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2522 break;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302523 case CAM_IFE_CSID_SET_CSID_DEBUG:
2524 rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args);
2525 break;
Jing Zhouff57d862017-03-21 00:54:25 -07002526 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002527 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2528 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002529 rc = -EINVAL;
2530 break;
2531 }
Jing Zhouff57d862017-03-21 00:54:25 -07002532
2533 return rc;
2534
2535}
2536
2537irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2538{
2539 struct cam_ife_csid_hw *csid_hw;
2540 struct cam_hw_soc_info *soc_info;
2541 struct cam_ife_csid_reg_offset *csid_reg;
2542 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0,
2543 irq_status_rdi[4];
Harsh Shahf7136392017-08-29 12:42:52 -07002544 uint32_t val;
Jing Zhouff57d862017-03-21 00:54:25 -07002545
2546 csid_hw = (struct cam_ife_csid_hw *)data;
2547
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002548 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002549
2550 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002551 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002552 return IRQ_HANDLED;
2553 }
2554
2555 csid_reg = csid_hw->csid_info->csid_reg;
2556 soc_info = &csid_hw->hw_info->soc_info;
2557
2558 /* read */
2559 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2560 csid_reg->cmn_reg->csid_top_irq_status_addr);
2561
2562 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2563 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2564
2565 if (csid_reg->cmn_reg->no_pix)
2566 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2567 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2568
2569
2570 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2571 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2572 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2573
2574 /* clear */
2575 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2576 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2577 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2578 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2579 if (csid_reg->cmn_reg->no_pix)
2580 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2581 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2582
2583 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2584 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2585 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2586 }
2587 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2588 csid_reg->cmn_reg->csid_irq_cmd_addr);
2589
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002590 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2591 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Jing Zhouff57d862017-03-21 00:54:25 -07002592
2593 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002594 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002595 complete(&csid_hw->csid_top_complete);
2596 return IRQ_HANDLED;
2597 }
2598
2599
2600 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002601 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002602 complete(&csid_hw->csid_csi2_complete);
2603 }
2604
2605 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002606 pr_err_ratelimited("CSID:%d lane 0 over flow",
2607 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002608 }
2609 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002610 pr_err_ratelimited("CSID:%d lane 1 over flow",
2611 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002612 }
2613 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002614 pr_err_ratelimited("CSID:%d lane 2 over flow",
2615 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002616 }
2617 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002618 pr_err_ratelimited("CSID:%d lane 3 over flow",
2619 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002620 }
2621 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002622 pr_err_ratelimited("CSID:%d TG OVER FLOW",
2623 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002624 }
2625 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002626 pr_err_ratelimited("CSID:%d CPHY_EOT_RECEPTION",
2627 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002628 }
2629 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002630 pr_err_ratelimited("CSID:%d CPHY_SOT_RECEPTION",
2631 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002632 }
2633 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002634 pr_err_ratelimited("CSID:%d CPHY_PH_CRC",
2635 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002636 }
2637
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302638 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
2639 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
2640 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_EOT_CAPTURED",
2641 csid_hw->hw_intf->hw_idx);
2642 }
2643 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED) {
2644 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_EOT_CAPTURED",
2645 csid_hw->hw_intf->hw_idx);
2646 }
2647 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED) {
2648 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_EOT_CAPTURED",
2649 csid_hw->hw_intf->hw_idx);
2650 }
2651 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED) {
2652 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_EOT_CAPTURED",
2653 csid_hw->hw_intf->hw_idx);
2654 }
2655 }
2656
2657 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) {
2658 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED) {
2659 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_SOT_CAPTURED",
2660 csid_hw->hw_intf->hw_idx);
2661 }
2662 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED) {
2663 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_SOT_CAPTURED",
2664 csid_hw->hw_intf->hw_idx);
2665 }
2666 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED) {
2667 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_SOT_CAPTURED",
2668 csid_hw->hw_intf->hw_idx);
2669 }
2670 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED) {
2671 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_SOT_CAPTURED",
2672 csid_hw->hw_intf->hw_idx);
2673 }
2674 }
2675
2676 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) &&
2677 (irq_status_rx & CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED)) {
2678 CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
2679 csid_hw->hw_intf->hw_idx);
2680 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2681 csid_reg->csi2_reg->
2682 csid_csi2_rx_captured_long_pkt_0_addr);
2683 CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
2684 csid_hw->hw_intf->hw_idx,
2685 (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
2686 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2687 csid_reg->csi2_reg->
2688 csid_csi2_rx_captured_long_pkt_1_addr);
2689 CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
2690 csid_hw->hw_intf->hw_idx, val);
2691 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2692 csid_reg->csi2_reg->
2693 csid_csi2_rx_captured_long_pkt_ftr_addr);
2694 CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
2695 csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
2696 }
2697 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) &&
2698 (irq_status_rx & CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED)) {
2699 CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
2700 csid_hw->hw_intf->hw_idx);
2701 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2702 csid_reg->csi2_reg->
2703 csid_csi2_rx_captured_short_pkt_0_addr);
2704 CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
2705 csid_hw->hw_intf->hw_idx,
2706 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2707 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2708 csid_reg->csi2_reg->
2709 csid_csi2_rx_captured_short_pkt_1_addr);
2710 CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d", val);
2711 }
2712
2713 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
2714 (irq_status_rx & CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED)) {
2715 CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
2716 csid_hw->hw_intf->hw_idx);
2717 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2718 csid_reg->csi2_reg->
2719 csid_csi2_rx_captured_cphy_pkt_hdr_addr);
2720 CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
2721 csid_hw->hw_intf->hw_idx,
2722 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2723 }
2724
Jing Zhouff57d862017-03-21 00:54:25 -07002725 /*read the IPP errors */
2726 if (csid_reg->cmn_reg->no_pix) {
2727 /* IPP reset done bit */
2728 if (irq_status_ipp &
2729 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002730 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002731 complete(&csid_hw->csid_ipp_complete);
2732 }
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302733
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302734 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
2735 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2736 CAM_ERR(CAM_ISP, "CSID:%d IPP SOF received",
2737 csid_hw->hw_intf->hw_idx);
2738
2739 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
2740 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2741 CAM_ERR(CAM_ISP, "CSID:%d IPP EOF received",
2742 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002743
2744 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2745 complete(&csid_hw->csid_ipp_complete);
2746
2747 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002748 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002749 csid_hw->hw_intf->hw_idx);
2750 /*Stop IPP path immediately */
2751 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2752 soc_info->reg_map[0].mem_base +
2753 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2754 }
2755 }
2756
2757 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2758 if (irq_status_rdi[i] &
2759 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302760 CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002761 complete(&csid_hw->csid_rdin_complete[i]);
2762 }
2763
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302764 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
2765 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2766 CAM_ERR(CAM_ISP, "CSID RDI:%d SOF received", i);
2767
2768 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) &&
2769 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2770 CAM_ERR(CAM_ISP, "CSID RDI:%d EOF received", i);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302771
Jing Zhouff57d862017-03-21 00:54:25 -07002772 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2773 complete(&csid_hw->csid_rdin_complete[i]);
2774
2775 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002776 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002777 csid_hw->hw_intf->hw_idx);
2778 /*Stop RDI path immediately */
2779 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2780 soc_info->reg_map[0].mem_base +
2781 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2782 }
2783 }
2784
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002785 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002786 return IRQ_HANDLED;
2787}
2788
2789int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2790 uint32_t csid_idx)
2791{
2792 int rc = -EINVAL;
2793 uint32_t i;
2794 struct cam_ife_csid_path_cfg *path_data;
2795 struct cam_ife_csid_cid_data *cid_data;
2796 struct cam_hw_info *csid_hw_info;
2797 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2798
2799 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002800 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002801 return rc;
2802 }
2803
2804 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2805 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2806
2807 ife_csid_hw->hw_intf = csid_hw_intf;
2808 ife_csid_hw->hw_info = csid_hw_info;
2809
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002810 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002811 ife_csid_hw->hw_intf->hw_type, csid_idx);
2812
2813
2814 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2815 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2816 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2817 init_completion(&ife_csid_hw->hw_info->hw_complete);
2818
2819 init_completion(&ife_csid_hw->csid_top_complete);
2820 init_completion(&ife_csid_hw->csid_csi2_complete);
2821 init_completion(&ife_csid_hw->csid_ipp_complete);
2822 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2823 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2824
2825
2826 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2827 cam_ife_csid_irq, ife_csid_hw);
2828 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002829 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002830 goto err;
2831 }
2832
2833 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2834 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2835 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2836 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2837 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2838 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2839 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2840 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2841 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2842 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2843 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2844
2845 /*Initialize the CID resoure */
2846 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2847 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2848 ife_csid_hw->cid_res[i].res_id = i;
2849 ife_csid_hw->cid_res[i].res_state =
2850 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2851 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2852
2853 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2854 GFP_KERNEL);
2855 if (!cid_data) {
2856 rc = -ENOMEM;
2857 goto err;
2858 }
2859 ife_csid_hw->cid_res[i].res_priv = cid_data;
2860 }
2861
2862 /* Initialize the IPP resources */
2863 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2864 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2865 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2866 ife_csid_hw->ipp_res.res_state =
2867 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2868 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2869 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2870 GFP_KERNEL);
2871 if (!path_data) {
2872 rc = -ENOMEM;
2873 goto err;
2874 }
2875 ife_csid_hw->ipp_res.res_priv = path_data;
2876 }
2877
2878 /* Initialize the RDI resource */
2879 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2880 i++) {
2881 /* res type is from RDI 0 to RDI3 */
2882 ife_csid_hw->rdi_res[i].res_type =
2883 CAM_ISP_RESOURCE_PIX_PATH;
2884 ife_csid_hw->rdi_res[i].res_id = i;
2885 ife_csid_hw->rdi_res[i].res_state =
2886 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2887 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2888
2889 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2890 GFP_KERNEL);
2891 if (!path_data) {
2892 rc = -ENOMEM;
2893 goto err;
2894 }
2895 ife_csid_hw->rdi_res[i].res_priv = path_data;
2896 }
2897
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302898 ife_csid_hw->csid_debug = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07002899 return 0;
2900err:
2901 if (rc) {
2902 kfree(ife_csid_hw->ipp_res.res_priv);
2903 for (i = 0; i <
2904 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2905 kfree(ife_csid_hw->rdi_res[i].res_priv);
2906
2907 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2908 kfree(ife_csid_hw->cid_res[i].res_priv);
2909
2910 }
2911
2912 return rc;
2913}
2914
2915
2916int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2917{
2918 int rc = -EINVAL;
2919 uint32_t i;
2920
2921 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002922 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002923 return rc;
2924 }
2925
2926 /* release the privdate data memory from resources */
2927 kfree(ife_csid_hw->ipp_res.res_priv);
2928 for (i = 0; i <
2929 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2930 i++) {
2931 kfree(ife_csid_hw->rdi_res[i].res_priv);
2932 }
2933 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2934 kfree(ife_csid_hw->cid_res[i].res_priv);
2935
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302936 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07002937
2938 return 0;
2939}