blob: daf515ad309db7f3dfccbf35fff222b0813c9227 [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
Harsh Shah3ba2a4f2017-10-23 16:20:44 -070035/*
36 * Constant Factors needed to change QTimer ticks to nanoseconds
37 * QTimer Freq = 19.2 MHz
38 * Time(us) = ticks/19.2
39 * Time(ns) = ticks/19.2 * 1000
40 */
41#define CAM_IFE_CSID_QTIMER_MUL_FACTOR 10000
42#define CAM_IFE_CSID_QTIMER_DIV_FACTOR 192
43
Jing Zhouff57d862017-03-21 00:54:25 -070044static int cam_ife_csid_is_ipp_format_supported(
Harsh Shahf7136392017-08-29 12:42:52 -070045 uint32_t in_format)
Jing Zhouff57d862017-03-21 00:54:25 -070046{
47 int rc = -EINVAL;
48
Harsh Shahf7136392017-08-29 12:42:52 -070049 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070050 case CAM_FORMAT_MIPI_RAW_6:
51 case CAM_FORMAT_MIPI_RAW_8:
52 case CAM_FORMAT_MIPI_RAW_10:
53 case CAM_FORMAT_MIPI_RAW_12:
54 case CAM_FORMAT_MIPI_RAW_14:
55 case CAM_FORMAT_MIPI_RAW_16:
56 case CAM_FORMAT_MIPI_RAW_20:
57 case CAM_FORMAT_DPCM_10_6_10:
58 case CAM_FORMAT_DPCM_10_8_10:
59 case CAM_FORMAT_DPCM_12_6_12:
60 case CAM_FORMAT_DPCM_12_8_12:
61 case CAM_FORMAT_DPCM_14_8_14:
62 case CAM_FORMAT_DPCM_14_10_14:
63 rc = 0;
64 break;
65 default:
66 break;
67 }
68 return rc;
69}
70
Harsh Shahf7136392017-08-29 12:42:52 -070071static int cam_ife_csid_get_format_rdi(
72 uint32_t in_format, uint32_t out_format,
73 uint32_t *decode_fmt, uint32_t *plain_fmt)
Jing Zhouff57d862017-03-21 00:54:25 -070074{
75 int rc = 0;
76
Harsh Shahf7136392017-08-29 12:42:52 -070077 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070078 case CAM_FORMAT_MIPI_RAW_6:
Harsh Shahf7136392017-08-29 12:42:52 -070079 switch (out_format) {
80 case CAM_FORMAT_MIPI_RAW_6:
81 *decode_fmt = 0xf;
82 break;
83 case CAM_FORMAT_PLAIN8:
84 *decode_fmt = 0x0;
85 *plain_fmt = 0x0;
86 break;
87 default:
88 rc = -EINVAL;
89 break;
90 }
Jing Zhouff57d862017-03-21 00:54:25 -070091 break;
92 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahf7136392017-08-29 12:42:52 -070093 switch (out_format) {
94 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahea34b602017-09-29 11:42:45 -070095 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -070096 *decode_fmt = 0xf;
97 break;
98 case CAM_FORMAT_PLAIN8:
99 *decode_fmt = 0x1;
100 *plain_fmt = 0x0;
101 break;
102 default:
103 rc = -EINVAL;
104 break;
105 }
Jing Zhouff57d862017-03-21 00:54:25 -0700106 break;
107 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700108 switch (out_format) {
109 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahea34b602017-09-29 11:42:45 -0700110 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700111 *decode_fmt = 0xf;
112 break;
113 case CAM_FORMAT_PLAIN16_10:
114 *decode_fmt = 0x2;
115 *plain_fmt = 0x1;
116 break;
117 default:
118 rc = -EINVAL;
119 break;
120 }
Jing Zhouff57d862017-03-21 00:54:25 -0700121 break;
122 case CAM_FORMAT_MIPI_RAW_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700123 switch (out_format) {
124 case CAM_FORMAT_MIPI_RAW_12:
125 *decode_fmt = 0xf;
126 break;
127 case CAM_FORMAT_PLAIN16_12:
128 *decode_fmt = 0x3;
129 *plain_fmt = 0x1;
130 break;
131 default:
132 rc = -EINVAL;
133 break;
134 }
Jing Zhouff57d862017-03-21 00:54:25 -0700135 break;
136 case CAM_FORMAT_MIPI_RAW_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700137 switch (out_format) {
138 case CAM_FORMAT_MIPI_RAW_14:
139 *decode_fmt = 0xf;
140 break;
141 case CAM_FORMAT_PLAIN16_14:
142 *decode_fmt = 0x4;
143 *plain_fmt = 0x1;
144 break;
145 default:
146 rc = -EINVAL;
147 break;
148 }
Jing Zhouff57d862017-03-21 00:54:25 -0700149 break;
150 case CAM_FORMAT_MIPI_RAW_16:
Harsh Shahf7136392017-08-29 12:42:52 -0700151 switch (out_format) {
152 case CAM_FORMAT_MIPI_RAW_16:
153 *decode_fmt = 0xf;
154 break;
155 case CAM_FORMAT_PLAIN16_16:
156 *decode_fmt = 0x5;
157 *plain_fmt = 0x1;
158 break;
159 default:
160 rc = -EINVAL;
161 break;
162 }
Jing Zhouff57d862017-03-21 00:54:25 -0700163 break;
164 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahf7136392017-08-29 12:42:52 -0700165 switch (out_format) {
166 case CAM_FORMAT_MIPI_RAW_20:
167 *decode_fmt = 0xf;
168 break;
169 case CAM_FORMAT_PLAIN32_20:
170 *decode_fmt = 0x6;
171 *plain_fmt = 0x2;
172 break;
173 default:
174 rc = -EINVAL;
175 break;
176 }
Jing Zhouff57d862017-03-21 00:54:25 -0700177 break;
178 case CAM_FORMAT_DPCM_10_6_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700179 *decode_fmt = 0x7;
180 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700181 break;
182 case CAM_FORMAT_DPCM_10_8_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700183 *decode_fmt = 0x8;
184 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700185 break;
186 case CAM_FORMAT_DPCM_12_6_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700187 *decode_fmt = 0x9;
188 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700189 break;
190 case CAM_FORMAT_DPCM_12_8_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700191 *decode_fmt = 0xA;
192 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700193 break;
194 case CAM_FORMAT_DPCM_14_8_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700195 *decode_fmt = 0xB;
196 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700197 break;
198 case CAM_FORMAT_DPCM_14_10_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700199 *decode_fmt = 0xC;
200 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700201 break;
202 default:
Harsh Shahf7136392017-08-29 12:42:52 -0700203 rc = -EINVAL;
204 break;
205 }
206
207 if (rc)
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530208 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d",
Harsh Shahf7136392017-08-29 12:42:52 -0700209 in_format, out_format);
210
211 return rc;
212}
213
214static int cam_ife_csid_get_format_ipp(
215 uint32_t in_format,
216 uint32_t *decode_fmt, uint32_t *plain_fmt)
217{
218 int rc = 0;
219
220 CAM_DBG(CAM_ISP, "input format:%d",
221 in_format);
222
223 switch (in_format) {
224 case CAM_FORMAT_MIPI_RAW_6:
225 *decode_fmt = 0;
226 *plain_fmt = 0;
227 break;
228 case CAM_FORMAT_MIPI_RAW_8:
229 *decode_fmt = 0x1;
230 *plain_fmt = 0;
231 break;
232 case CAM_FORMAT_MIPI_RAW_10:
233 *decode_fmt = 0x2;
234 *plain_fmt = 0x1;
235 break;
236 case CAM_FORMAT_MIPI_RAW_12:
237 *decode_fmt = 0x3;
238 *plain_fmt = 0x1;
239 break;
240 case CAM_FORMAT_MIPI_RAW_14:
241 *decode_fmt = 0x4;
242 *plain_fmt = 0x1;
243 break;
244 case CAM_FORMAT_MIPI_RAW_16:
245 *decode_fmt = 0x5;
246 *plain_fmt = 0x1;
247 break;
248 case CAM_FORMAT_MIPI_RAW_20:
249 *decode_fmt = 0x6;
250 *plain_fmt = 0x2;
251 break;
252 case CAM_FORMAT_DPCM_10_6_10:
253 *decode_fmt = 0x7;
254 *plain_fmt = 0x1;
255 break;
256 case CAM_FORMAT_DPCM_10_8_10:
257 *decode_fmt = 0x8;
258 *plain_fmt = 0x1;
259 break;
260 case CAM_FORMAT_DPCM_12_6_12:
261 *decode_fmt = 0x9;
262 *plain_fmt = 0x1;
263 break;
264 case CAM_FORMAT_DPCM_12_8_12:
265 *decode_fmt = 0xA;
266 *plain_fmt = 0x1;
267 break;
268 case CAM_FORMAT_DPCM_14_8_14:
269 *decode_fmt = 0xB;
270 *plain_fmt = 0x1;
271 break;
272 case CAM_FORMAT_DPCM_14_10_14:
273 *decode_fmt = 0xC;
274 *plain_fmt = 0x1;
275 break;
276 default:
277 CAM_ERR(CAM_ISP, "Unsupported format %d",
278 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700279 rc = -EINVAL;
280 }
281
Harsh Shahf7136392017-08-29 12:42:52 -0700282 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
283 *decode_fmt, *plain_fmt);
284
Jing Zhouff57d862017-03-21 00:54:25 -0700285 return rc;
286}
287
288static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
289 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
Jing Zhou4a0a1112017-11-14 16:59:49 -0800290 uint32_t res_type, int pixel_count)
Jing Zhouff57d862017-03-21 00:54:25 -0700291{
292 int rc = 0;
293 struct cam_ife_csid_cid_data *cid_data;
294 uint32_t i = 0, j = 0;
295
296 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
297 if (csid_hw->cid_res[i].res_state >=
298 CAM_ISP_RESOURCE_STATE_RESERVED) {
299 cid_data = (struct cam_ife_csid_cid_data *)
300 csid_hw->cid_res[i].res_priv;
301 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
302 if (cid_data->tpg_set) {
303 cid_data->cnt++;
304 *res = &csid_hw->cid_res[i];
305 break;
306 }
307 } else {
Jing Zhou4a0a1112017-11-14 16:59:49 -0800308 if (cid_data->vc == vc && cid_data->dt == dt &&
309 cid_data->pixel_count == pixel_count) {
Jing Zhouff57d862017-03-21 00:54:25 -0700310 cid_data->cnt++;
311 *res = &csid_hw->cid_res[i];
312 break;
313 }
314 }
315 }
316 }
317
318 if (i == CAM_IFE_CSID_CID_RES_MAX) {
319 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700320 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
321 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700322 rc = -EINVAL;
323 }
324
325 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
326 if (csid_hw->cid_res[j].res_state ==
327 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
328 cid_data = (struct cam_ife_csid_cid_data *)
329 csid_hw->cid_res[j].res_priv;
330 cid_data->vc = vc;
331 cid_data->dt = dt;
332 cid_data->cnt = 1;
Jing Zhou4a0a1112017-11-14 16:59:49 -0800333 cid_data->pixel_count = pixel_count;
Jing Zhouff57d862017-03-21 00:54:25 -0700334 csid_hw->cid_res[j].res_state =
335 CAM_ISP_RESOURCE_STATE_RESERVED;
336 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700337 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700338 csid_hw->hw_intf->hw_idx,
339 csid_hw->cid_res[j].res_id);
340 break;
341 }
342 }
343
344 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700345 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
346 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700347 rc = -EINVAL;
348 }
349 }
350
351 return rc;
352}
353
354
355static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
356{
357 struct cam_hw_soc_info *soc_info;
358 struct cam_ife_csid_reg_offset *csid_reg;
359 int rc = 0;
360 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
361 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
362
363 soc_info = &csid_hw->hw_info->soc_info;
364 csid_reg = csid_hw->csid_info->csid_reg;
365
366 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700367 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
368 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700369 csid_hw->hw_info->hw_state);
370 return -EINVAL;
371 }
372
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700373 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700374 csid_hw->hw_intf->hw_idx);
375
376 init_completion(&csid_hw->csid_top_complete);
377
378 /* Save interrupt mask registers values*/
379 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
380 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
381
382 if (csid_reg->cmn_reg->no_pix)
383 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
384 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
385
386 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
387 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
388 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
389 }
390
391 /* Mask all interrupts */
392 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
393 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
394
395 if (csid_reg->cmn_reg->no_pix)
396 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
397 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
398
399 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
400 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
401 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
402
403 /* clear all interrupts */
404 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
405 csid_reg->cmn_reg->csid_top_irq_clear_addr);
406
407 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
408 soc_info->reg_map[0].mem_base +
409 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
410
411 if (csid_reg->cmn_reg->no_pix)
412 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
413 soc_info->reg_map[0].mem_base +
414 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
415
416 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
417 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
418 soc_info->reg_map[0].mem_base +
419 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
420
421 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
422 csid_reg->cmn_reg->csid_irq_cmd_addr);
423
424 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
425 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
426
427 /* enable the IPP and RDI format measure */
428 if (csid_reg->cmn_reg->no_pix)
429 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
430 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
431
432 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
433 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
434 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
435
436 /* perform the top CSID HW reset */
437 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
438 soc_info->reg_map[0].mem_base +
439 csid_reg->cmn_reg->csid_rst_strobes_addr);
440
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700441 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700442 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
443 msecs_to_jiffies(IFE_CSID_TIMEOUT));
444 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700445 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
446 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700447 if (rc == 0)
448 rc = -ETIMEDOUT;
449 } else {
450 rc = 0;
451 }
452
453 /*restore all interrupt masks */
454 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
455 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
456
457 if (csid_reg->cmn_reg->no_pix)
458 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
459 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
460
461 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
462 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
463 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
464
465 return rc;
466}
467
468static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
469 struct cam_csid_reset_cfg_args *reset)
470{
471 int rc = 0;
472 struct cam_hw_soc_info *soc_info;
473 struct cam_isp_resource_node *res;
474 struct cam_ife_csid_reg_offset *csid_reg;
475 uint32_t reset_strb_addr, reset_strb_val, val, id;
476 struct completion *complete;
477
478 csid_reg = csid_hw->csid_info->csid_reg;
479 soc_info = &csid_hw->hw_info->soc_info;
480 res = reset->node_res;
481
482 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700483 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
484 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700485 csid_hw->hw_info->hw_state);
486 return -EINVAL;
487 }
488
489 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700490 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
491 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700492 rc = -EINVAL;
493 goto end;
494 }
495
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700496 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700497 csid_hw->hw_intf->hw_idx, res->res_id);
498
499 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
500 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700501 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
502 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700503 res->res_id);
504 return -EINVAL;
505 }
506
507 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
508 complete = &csid_hw->csid_ipp_complete;
509
510 /* Enable path reset done interrupt */
511 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
512 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
513 val |= CSID_PATH_INFO_RST_DONE;
514 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
515 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
516
517 } else {
518 id = res->res_id;
519 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700520 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
521 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700522 res->res_id);
523 return -EINVAL;
524 }
525
526 reset_strb_addr =
527 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
528 complete =
529 &csid_hw->csid_rdin_complete[id];
530
531 /* Enable path reset done interrupt */
532 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
533 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
534 val |= CSID_PATH_INFO_RST_DONE;
535 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
536 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
537 }
538
539 init_completion(complete);
540 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
541
542 /* Enable the Test gen before reset */
543 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
544 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
545
546 /* Reset the corresponding ife csid path */
547 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
548 reset_strb_addr);
549
550 rc = wait_for_completion_timeout(complete,
551 msecs_to_jiffies(IFE_CSID_TIMEOUT));
552 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700553 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
554 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700555 res->res_id, rc);
556 if (rc == 0)
557 rc = -ETIMEDOUT;
558 }
559
560 /* Disable Test Gen after reset*/
561 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
562 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
563
564end:
565 return rc;
566
567}
568
569static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
570 struct cam_csid_hw_reserve_resource_args *cid_reserv)
571{
572 int rc = 0;
Jing Zhou4a0a1112017-11-14 16:59:49 -0800573 uint32_t i;
Jing Zhouff57d862017-03-21 00:54:25 -0700574 struct cam_ife_csid_cid_data *cid_data;
575
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700576 CAM_DBG(CAM_ISP,
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530577 "CSID:%d res_sel:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700578 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700579 cid_reserv->in_port->res_type,
580 cid_reserv->in_port->lane_type,
581 cid_reserv->in_port->lane_num,
582 cid_reserv->in_port->dt,
583 cid_reserv->in_port->vc);
584
585 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700586 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
587 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700588 cid_reserv->in_port->res_type);
589 rc = -EINVAL;
590 goto end;
591 }
592
593 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
594 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700595 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
596 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700597 cid_reserv->in_port->lane_type);
598 rc = -EINVAL;
599 goto end;
600 }
601
602 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
603 cid_reserv->in_port->lane_num > 4) &&
604 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700605 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
606 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700607 cid_reserv->in_port->lane_num);
608 rc = -EINVAL;
609 goto end;
610 }
611 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
612 cid_reserv->in_port->lane_num > 3) &&
613 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700614 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
615 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700616 cid_reserv->in_port->lane_type,
617 cid_reserv->in_port->lane_num);
618 rc = -EINVAL;
619 goto end;
620 }
621
622 /* CSID CSI2 v2.0 supports 31 vc */
623 if (cid_reserv->in_port->dt > 0x3f ||
624 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700625 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
626 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700627 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
628 rc = -EINVAL;
629 goto end;
630 }
631
632 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
633 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
634 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700635 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
636 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700637 cid_reserv->in_port->format);
638 rc = -EINVAL;
639 goto end;
640 }
641
Harsh Shah398b0122017-09-28 15:36:39 -0700642 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_PHY_3 &&
643 csid_hw->hw_intf->hw_idx != 2) {
644 rc = -EINVAL;
645 goto end;
646 }
647
Jing Zhouff57d862017-03-21 00:54:25 -0700648 if (csid_hw->csi2_reserve_cnt) {
649 /* current configure res type should match requested res type */
650 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
651 rc = -EINVAL;
652 goto end;
653 }
654
655 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
656 if (csid_hw->csi2_rx_cfg.lane_cfg !=
657 cid_reserv->in_port->lane_cfg ||
658 csid_hw->csi2_rx_cfg.lane_type !=
659 cid_reserv->in_port->lane_type ||
660 csid_hw->csi2_rx_cfg.lane_num !=
661 cid_reserv->in_port->lane_num) {
662 rc = -EINVAL;
663 goto end;
664 }
665 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700666 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700667 cid_reserv->in_port->format ||
668 csid_hw->tpg_cfg.width !=
669 cid_reserv->in_port->left_width ||
670 csid_hw->tpg_cfg.height !=
671 cid_reserv->in_port->height ||
672 csid_hw->tpg_cfg.test_pattern !=
673 cid_reserv->in_port->test_pattern) {
674 rc = -EINVAL;
675 goto end;
676 }
677 }
678 }
679
680 if (!csid_hw->csi2_reserve_cnt) {
681 csid_hw->res_type = cid_reserv->in_port->res_type;
682 /* Take the first CID resource*/
683 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
684 cid_data = (struct cam_ife_csid_cid_data *)
685 csid_hw->cid_res[0].res_priv;
686
687 csid_hw->csi2_rx_cfg.lane_cfg =
688 cid_reserv->in_port->lane_cfg;
689 csid_hw->csi2_rx_cfg.lane_type =
690 cid_reserv->in_port->lane_type;
691 csid_hw->csi2_rx_cfg.lane_num =
692 cid_reserv->in_port->lane_num;
693
694 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
695 csid_hw->csi2_rx_cfg.phy_sel = 0;
696 if (cid_reserv->in_port->format >
697 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700698 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700699 rc = -EINVAL;
700 goto end;
701 }
Harsh Shahf7136392017-08-29 12:42:52 -0700702 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700703 cid_reserv->in_port->format;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530704 csid_hw->tpg_cfg.usage_type =
705 cid_reserv->in_port->usage_type;
706 if (cid_reserv->in_port->usage_type)
707 csid_hw->tpg_cfg.width =
708 (cid_reserv->in_port->right_stop + 1);
709 else
710 csid_hw->tpg_cfg.width =
711 cid_reserv->in_port->left_width;
712
Jing Zhouff57d862017-03-21 00:54:25 -0700713 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
714 csid_hw->tpg_cfg.test_pattern =
715 cid_reserv->in_port->test_pattern;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530716
717 CAM_DBG(CAM_ISP, "CSID:%d TPG width:%d height:%d",
718 csid_hw->hw_intf->hw_idx,
719 csid_hw->tpg_cfg.width,
720 csid_hw->tpg_cfg.height);
721
Jing Zhouff57d862017-03-21 00:54:25 -0700722 cid_data->tpg_set = 1;
723 } else {
724 csid_hw->csi2_rx_cfg.phy_sel =
725 (cid_reserv->in_port->res_type & 0xFF) - 1;
726 }
727
728 cid_data->vc = cid_reserv->in_port->vc;
729 cid_data->dt = cid_reserv->in_port->dt;
730 cid_data->cnt = 1;
Jing Zhou4a0a1112017-11-14 16:59:49 -0800731 cid_data->pixel_count = cid_reserv->pixel_count;
Jing Zhouff57d862017-03-21 00:54:25 -0700732 cid_reserv->node_res = &csid_hw->cid_res[0];
733 csid_hw->csi2_reserve_cnt++;
734
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700735 CAM_DBG(CAM_ISP,
736 "CSID:%d CID :%d resource acquired successfully",
737 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700738 cid_reserv->node_res->res_id);
739 } else {
Jing Zhou4a0a1112017-11-14 16:59:49 -0800740 if (cid_reserv->pixel_count > 0) {
741 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
742 cid_data = (struct cam_ife_csid_cid_data *)
743 csid_hw->cid_res[i].res_priv;
744 if ((csid_hw->cid_res[i].res_state >=
745 CAM_ISP_RESOURCE_STATE_RESERVED) &&
746 cid_data->pixel_count > 0) {
747 CAM_DBG(CAM_ISP,
748 "CSID:%d IPP resource is full");
749 rc = -EINVAL;
750 goto end;
751 }
752 }
753 }
754
755 rc = cam_ife_csid_cid_get(csid_hw,
756 &cid_reserv->node_res,
757 cid_reserv->in_port->vc,
758 cid_reserv->in_port->dt,
759 cid_reserv->in_port->res_type,
760 cid_reserv->pixel_count);
Jing Zhouff57d862017-03-21 00:54:25 -0700761 /* if success then increment the reserve count */
762 if (!rc) {
763 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700764 CAM_ERR(CAM_ISP,
765 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700766 csid_hw->hw_intf->hw_idx);
767 rc = -EINVAL;
768 } else {
769 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700770 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700771 csid_hw->hw_intf->hw_idx,
772 cid_reserv->node_res->res_id);
773 }
774 }
775 }
776
777end:
778 return rc;
779}
780
781
782static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
783 struct cam_csid_hw_reserve_resource_args *reserve)
784{
785 int rc = 0;
786 struct cam_ife_csid_path_cfg *path_data;
787 struct cam_isp_resource_node *res;
788
789 /* CSID CSI2 v2.0 supports 31 vc */
790 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
791 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700792 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
793 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700794 reserve->in_port->vc, reserve->in_port->dt,
795 reserve->sync_mode);
796 rc = -EINVAL;
797 goto end;
798 }
799
800 switch (reserve->res_id) {
801 case CAM_IFE_PIX_PATH_RES_IPP:
802 if (csid_hw->ipp_res.res_state !=
803 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700804 CAM_DBG(CAM_ISP,
805 "CSID:%d IPP resource not available %d",
806 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700807 csid_hw->ipp_res.res_state);
808 rc = -EINVAL;
809 goto end;
810 }
811
812 if (cam_ife_csid_is_ipp_format_supported(
813 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700814 CAM_ERR(CAM_ISP,
815 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700816 csid_hw->hw_intf->hw_idx, reserve->res_id,
817 reserve->in_port->format);
818 rc = -EINVAL;
819 goto end;
820 }
821
822 /* assign the IPP resource */
823 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700824 CAM_DBG(CAM_ISP,
825 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700826 csid_hw->hw_intf->hw_idx, res->res_id);
827
828 break;
829 case CAM_IFE_PIX_PATH_RES_RDI_0:
830 case CAM_IFE_PIX_PATH_RES_RDI_1:
831 case CAM_IFE_PIX_PATH_RES_RDI_2:
832 case CAM_IFE_PIX_PATH_RES_RDI_3:
833 if (csid_hw->rdi_res[reserve->res_id].res_state !=
834 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700835 CAM_DBG(CAM_ISP,
836 "CSID:%d RDI:%d resource not available %d",
837 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700838 reserve->res_id,
839 csid_hw->rdi_res[reserve->res_id].res_state);
840 rc = -EINVAL;
841 goto end;
842 } else {
843 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700844 CAM_DBG(CAM_ISP,
845 "CSID:%d RDI resource:%d acquire success",
846 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700847 res->res_id);
848 }
849
850 break;
851 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700852 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700853 csid_hw->hw_intf->hw_idx, reserve->res_id);
854 rc = -EINVAL;
855 goto end;
856 }
857
858 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
859 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
860
861 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700862 path_data->in_format = reserve->in_port->format;
863 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700864 path_data->master_idx = reserve->master_idx;
865 path_data->sync_mode = reserve->sync_mode;
866 path_data->height = reserve->in_port->height;
867 path_data->start_line = reserve->in_port->line_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530868 path_data->end_line = reserve->in_port->line_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700869 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
870 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
871 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
872 } else {
873 path_data->dt = reserve->in_port->dt;
874 path_data->vc = reserve->in_port->vc;
875 }
876
877 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
878 path_data->crop_enable = 1;
879 path_data->start_pixel = reserve->in_port->left_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530880 path_data->end_pixel = reserve->in_port->left_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700881 path_data->width = reserve->in_port->left_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530882 CAM_DBG(CAM_ISP, "CSID:%dmaster:startpixel 0x%x endpixel:0x%x",
883 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
884 path_data->end_pixel);
885 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
886 csid_hw->hw_intf->hw_idx, path_data->start_line,
887 path_data->end_line);
Jing Zhouff57d862017-03-21 00:54:25 -0700888 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
889 path_data->crop_enable = 1;
890 path_data->start_pixel = reserve->in_port->right_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530891 path_data->end_pixel = reserve->in_port->right_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700892 path_data->width = reserve->in_port->right_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530893 CAM_DBG(CAM_ISP, "CSID:%d slave:start:0x%x end:0x%x width 0x%x",
894 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
895 path_data->end_pixel, path_data->width);
896 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
897 csid_hw->hw_intf->hw_idx, path_data->start_line,
898 path_data->end_line);
Harsh Shahf7136392017-08-29 12:42:52 -0700899 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700900 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700901 path_data->width = reserve->in_port->left_width;
902 path_data->start_pixel = reserve->in_port->left_start;
903 }
Jing Zhouff57d862017-03-21 00:54:25 -0700904
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530905 CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
Harsh Shahf7136392017-08-29 12:42:52 -0700906 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700907 reserve->node_res = res;
908
909end:
910 return rc;
911}
912
913static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
914{
915 int rc = 0;
916 struct cam_ife_csid_reg_offset *csid_reg;
917 struct cam_hw_soc_info *soc_info;
918 uint32_t i, status, val;
919
920 csid_reg = csid_hw->csid_info->csid_reg;
921 soc_info = &csid_hw->hw_info->soc_info;
922
923 /* overflow check before increment */
924 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700925 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
926 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700927 return -EINVAL;
928 }
929
930 /* Increment ref Count */
931 csid_hw->hw_info->open_count++;
932 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700933 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700934 return rc;
935 }
936
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700937 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700938 csid_hw->hw_intf->hw_idx);
939
940 rc = cam_ife_csid_enable_soc_resources(soc_info);
941 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700942 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700943 csid_hw->hw_intf->hw_idx);
944 goto err;
945 }
946
947
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700948 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700949 csid_hw->hw_intf->hw_idx);
950
951 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
952 /* Enable the top IRQ interrupt */
953 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
954 csid_reg->cmn_reg->csid_top_irq_mask_addr);
955
956 rc = cam_ife_csid_global_reset(csid_hw);
957 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700958 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
959 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700960 rc = -ETIMEDOUT;
961 goto disable_soc;
962 }
963
964 /*
965 * Reset the SW registers
966 * SW register reset also reset the mask irq, so poll the irq status
967 * to check the reset complete.
968 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700969 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700970 csid_hw->hw_intf->hw_idx);
971
972 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
973 soc_info->reg_map[0].mem_base +
974 csid_reg->cmn_reg->csid_rst_strobes_addr);
975
976 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
977 csid_reg->cmn_reg->csid_top_irq_status_addr,
978 status, (status & 0x1) == 0x1,
979 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
980 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700981 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700982 rc = -ETIMEDOUT;
983 goto disable_soc;
984 }
985
986 /* clear all interrupts */
987 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
988 csid_reg->cmn_reg->csid_top_irq_clear_addr);
989
990 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
991 soc_info->reg_map[0].mem_base +
992 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
993
994 if (csid_reg->cmn_reg->no_pix)
995 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
996 soc_info->reg_map[0].mem_base +
997 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
998
999 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
1000 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
1001 soc_info->reg_map[0].mem_base +
1002 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
1003
1004 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1005 csid_reg->cmn_reg->csid_irq_cmd_addr);
1006
1007 /* Enable the top IRQ interrupt */
1008 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1009 csid_reg->cmn_reg->csid_top_irq_mask_addr);
1010
1011 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1012 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001013 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001014 csid_hw->hw_intf->hw_idx, val);
1015
1016 return 0;
1017
1018disable_soc:
1019 cam_ife_csid_disable_soc_resources(soc_info);
1020 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
1021err:
1022 csid_hw->hw_info->open_count--;
1023 return rc;
1024}
1025
1026static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
1027{
1028 int rc = 0;
1029 struct cam_hw_soc_info *soc_info;
1030 struct cam_ife_csid_reg_offset *csid_reg;
1031
1032
1033 /* Decrement ref Count */
1034 if (csid_hw->hw_info->open_count)
1035 csid_hw->hw_info->open_count--;
1036 if (csid_hw->hw_info->open_count)
1037 return rc;
1038
1039 soc_info = &csid_hw->hw_info->soc_info;
1040 csid_reg = csid_hw->csid_info->csid_reg;
1041
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001042 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -07001043 csid_hw->hw_intf->hw_idx);
1044
1045 /*disable the top IRQ interrupt */
1046 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1047 csid_reg->cmn_reg->csid_top_irq_mask_addr);
1048
1049 rc = cam_ife_csid_disable_soc_resources(soc_info);
1050 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001051 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
1052 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001053
1054 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
1055 return rc;
1056}
1057
1058
1059static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
1060 struct cam_isp_resource_node *res)
1061{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301062 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001063 uint32_t val = 0;
1064 struct cam_hw_soc_info *soc_info;
1065
1066 csid_hw->tpg_start_cnt++;
1067 if (csid_hw->tpg_start_cnt == 1) {
1068 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001069 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1070 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001071
1072 soc_info = &csid_hw->hw_info->soc_info;
1073 {
1074 uint32_t val;
1075 uint32_t i;
1076 uint32_t base = 0x600;
1077
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001078 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001079 for (i = 0; i < 16; i++) {
1080 val = cam_io_r_mb(
1081 soc_info->reg_map[0].mem_base +
1082 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001083 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001084 (base + i*4), val);
1085 }
1086
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001087 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001088 base = 0x200;
1089 for (i = 0; i < 10; i++) {
1090 val = cam_io_r_mb(
1091 soc_info->reg_map[0].mem_base +
1092 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001093 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001094 (base + i*4), val);
1095 }
1096
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001097 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001098 base = 0x100;
1099 for (i = 0; i < 5; i++) {
1100 val = cam_io_r_mb(
1101 soc_info->reg_map[0].mem_base +
1102 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001103 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001104 (base + i*4), val);
1105 }
1106 }
1107
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301108 /* Enable the IFE force clock on for dual isp case */
1109 if (csid_hw->tpg_cfg.usage_type) {
1110 rc = cam_ife_csid_enable_ife_force_clock_on(soc_info,
1111 csid_hw->csid_info->csid_reg->tpg_reg->
1112 tpg_cpas_ife_reg_offset);
1113 if (rc)
1114 return rc;
1115 }
1116
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001117 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001118 val = (4 << 20);
1119 val |= (0x80 << 8);
1120 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1121 val |= 7;
1122 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1123 csid_hw->csid_info->csid_reg->tpg_reg->
1124 csid_tpg_ctrl_addr);
1125
1126 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001127 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001128 }
1129
1130 return 0;
1131}
1132
1133static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1134 struct cam_isp_resource_node *res)
1135{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301136 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001137 struct cam_hw_soc_info *soc_info;
1138
1139 if (csid_hw->tpg_start_cnt)
1140 csid_hw->tpg_start_cnt--;
1141
1142 if (csid_hw->tpg_start_cnt)
1143 return 0;
1144
1145 soc_info = &csid_hw->hw_info->soc_info;
1146
1147 /* disable the TPG */
1148 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001149 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1150 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001151
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301152 /* Disable the IFE force clock on for dual isp case */
1153 if (csid_hw->tpg_cfg.usage_type)
1154 rc = cam_ife_csid_disable_ife_force_clock_on(soc_info,
1155 csid_hw->csid_info->csid_reg->tpg_reg->
1156 tpg_cpas_ife_reg_offset);
1157
Jing Zhouff57d862017-03-21 00:54:25 -07001158 /*stop the TPG */
1159 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1160 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1161 }
1162
1163 return 0;
1164}
1165
1166
1167static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1168 struct cam_isp_resource_node *res)
1169{
1170 struct cam_ife_csid_reg_offset *csid_reg;
1171 struct cam_hw_soc_info *soc_info;
1172 uint32_t val = 0;
1173
1174 csid_reg = csid_hw->csid_info->csid_reg;
1175 soc_info = &csid_hw->hw_info->soc_info;
1176
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001177 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1178 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001179
1180 /* configure one DT, infinite frames */
1181 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1182 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1183 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1184
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301185 /* vertical blanking count = 0x3FF, horzontal blanking count = 0x740*/
1186 val = (0x3FF << 12) | 0x740;
Jing Zhouff57d862017-03-21 00:54:25 -07001187 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1188 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1189
1190 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1191 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1192
1193 val = csid_hw->tpg_cfg.width << 16 |
1194 csid_hw->tpg_cfg.height;
1195 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1196 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1197
1198 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1199 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1200
1201 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001202 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001203 * it is one larger than the register spec format.
1204 */
Harsh Shahf7136392017-08-29 12:42:52 -07001205 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001206 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1207 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1208
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001209 /* static frame with split color bar */
1210 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001211 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1212 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1213 /* config pix pattern */
1214 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1215 soc_info->reg_map[0].mem_base +
1216 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1217
1218 return 0;
1219}
1220
1221static int cam_ife_csid_enable_csi2(
1222 struct cam_ife_csid_hw *csid_hw,
1223 struct cam_isp_resource_node *res)
1224{
1225 int rc = 0;
1226 struct cam_ife_csid_reg_offset *csid_reg;
1227 struct cam_hw_soc_info *soc_info;
1228 struct cam_ife_csid_cid_data *cid_data;
1229 uint32_t val = 0;
1230
1231 csid_reg = csid_hw->csid_info->csid_reg;
1232 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001233 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1234 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001235
1236 /* overflow check before increment */
1237 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001238 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1239 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001240 return -EINVAL;
1241 }
1242
1243 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1244
1245 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1246 csid_hw->csi2_cfg_cnt++;
1247 if (csid_hw->csi2_cfg_cnt > 1)
1248 return rc;
1249
1250 /* rx cfg0 */
1251 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1252 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1253 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001254 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001255 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1256 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1257
1258 /* rx cfg1*/
1259 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1260 /* if VC value is more than 3 than set full width of VC */
1261 if (cid_data->vc > 3)
1262 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1263
1264 /* enable packet ecc correction */
1265 val |= 1;
1266 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1267 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1268
1269 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1270 /* Config the TPG */
1271 rc = cam_ife_csid_config_tpg(csid_hw, res);
1272 if (rc) {
1273 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1274 return rc;
1275 }
1276 }
1277
1278 /*Enable the CSI2 rx inerrupts */
1279 val = CSID_CSI2_RX_INFO_RST_DONE |
1280 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1281 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1282 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1283 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1284 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1285 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1286 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
Harsh Shah1b8eb232017-10-09 19:20:52 -07001287 CSID_CSI2_RX_ERROR_CRC |
1288 CSID_CSI2_RX_ERROR_ECC |
1289 CSID_CSI2_RX_ERROR_MMAPPED_VC_DT |
1290 CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW |
1291 CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME |
Jing Zhouff57d862017-03-21 00:54:25 -07001292 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301293
1294 /* Enable the interrupt based on csid debug info set */
1295 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ)
1296 val |= CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED |
1297 CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED |
1298 CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED |
1299 CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED;
1300
1301 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ)
1302 val |= CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED |
1303 CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED |
1304 CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED |
1305 CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED;
1306
1307 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1308 val |= CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED;
1309
1310 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1311 val |= CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED;
1312 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1313 val |= CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED;
1314
Jing Zhouff57d862017-03-21 00:54:25 -07001315 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1316 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1317
1318 return 0;
1319}
1320
1321static int cam_ife_csid_disable_csi2(
1322 struct cam_ife_csid_hw *csid_hw,
1323 struct cam_isp_resource_node *res)
1324{
1325 struct cam_ife_csid_reg_offset *csid_reg;
1326 struct cam_hw_soc_info *soc_info;
1327
1328 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001329 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1330 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001331 return -EINVAL;
1332 }
1333
1334 csid_reg = csid_hw->csid_info->csid_reg;
1335 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001336 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1337 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001338
1339 if (csid_hw->csi2_cfg_cnt)
1340 csid_hw->csi2_cfg_cnt--;
1341
1342 if (csid_hw->csi2_cfg_cnt)
1343 return 0;
1344
1345 /*Disable the CSI2 rx inerrupts */
1346 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1347 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1348
1349 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1350
1351 return 0;
1352}
1353
1354static int cam_ife_csid_init_config_ipp_path(
1355 struct cam_ife_csid_hw *csid_hw,
1356 struct cam_isp_resource_node *res)
1357{
1358 int rc = 0;
1359 struct cam_ife_csid_path_cfg *path_data;
1360 struct cam_ife_csid_reg_offset *csid_reg;
1361 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001362 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001363
1364 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1365 csid_reg = csid_hw->csid_info->csid_reg;
1366 soc_info = &csid_hw->hw_info->soc_info;
1367
1368 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001369 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1370 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001371 res->res_id);
1372 return -EINVAL;
1373 }
1374
Harsh Shahf7136392017-08-29 12:42:52 -07001375 CAM_DBG(CAM_ISP, "Config IPP Path");
1376 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1377 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001378 if (rc)
1379 return rc;
1380
Jing Zhoubb536a82017-05-18 15:20:38 -07001381 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001382 * configure the IPP and enable the time stamp capture.
1383 * enable the HW measrurement blocks
1384 */
1385 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1386 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1387 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001388 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301389 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001390 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301391 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001392 csid_reg->cmn_reg->crop_v_en_shift_val) |
1393 (1 << 1) | 1;
1394 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1395 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1396 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1397
Jing Zhoudedc4762017-06-19 17:45:36 +05301398 /* select the post irq sub sample strobe for time stamp capture */
1399 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1400 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1401
Jing Zhouff57d862017-03-21 00:54:25 -07001402 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301403 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001404 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301405 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001406 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1407 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301408 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1409 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001410
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301411 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001412 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301413 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001414 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1415 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301416 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1417 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001418 }
1419
1420 /* set frame drop pattern to 0 and period to 1 */
1421 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1422 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1423 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1424 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1425 /* set irq sub sample pattern to 0 and period to 1 */
1426 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1427 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1428 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1429 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1430 /* set pixel drop pattern to 0 and period to 1 */
1431 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1432 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1433 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1434 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1435 /* set line drop pattern to 0 and period to 1 */
1436 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1437 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1438 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1439 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1440
1441 /*Set master or slave IPP */
1442 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1443 /*Set halt mode as master */
1444 val = CSID_HALT_MODE_MASTER << 2;
1445 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1446 /*Set halt mode as slave and set master idx */
1447 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1448 else
1449 /* Default is internal halt mode */
1450 val = 0;
1451
1452 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1453 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1454
1455 /* Enable the IPP path */
1456 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1457 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1458 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1459 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1460 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1461
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301462 /* configure the rx packet capture based on csid debug set */
1463 val = 0;
1464 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1465 val = ((1 <<
1466 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1467 (path_data->vc <<
1468 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1469
1470 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1471 val |= ((1 <<
1472 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1473 (path_data->dt <<
1474 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1475 (path_data->vc <<
1476 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1477
1478 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1479 val |= ((1 <<
1480 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1481 (path_data->dt <<
1482 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1483 (path_data->vc <<
1484 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1485
1486 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1487 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1488 CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val);
1489
Jing Zhouff57d862017-03-21 00:54:25 -07001490 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1491
1492 return rc;
1493}
1494
1495static int cam_ife_csid_deinit_ipp_path(
1496 struct cam_ife_csid_hw *csid_hw,
1497 struct cam_isp_resource_node *res)
1498{
1499 int rc = 0;
1500 struct cam_ife_csid_reg_offset *csid_reg;
1501 struct cam_hw_soc_info *soc_info;
1502 uint32_t val = 0;
1503
1504 csid_reg = csid_hw->csid_info->csid_reg;
1505 soc_info = &csid_hw->hw_info->soc_info;
1506
1507 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001508 CAM_ERR(CAM_ISP,
1509 "CSID:%d Res type %d res_id:%d in wrong state %d",
1510 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001511 res->res_type, res->res_id, res->res_state);
1512 rc = -EINVAL;
1513 }
1514
1515 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001516 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1517 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001518 res->res_id);
1519 rc = -EINVAL;
1520 }
1521
1522 /* Disable the IPP path */
1523 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1524 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1525 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1526 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1527 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1528
1529 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1530 return rc;
1531}
1532
1533static int cam_ife_csid_enable_ipp_path(
1534 struct cam_ife_csid_hw *csid_hw,
1535 struct cam_isp_resource_node *res)
1536{
1537 struct cam_ife_csid_reg_offset *csid_reg;
1538 struct cam_hw_soc_info *soc_info;
1539 struct cam_ife_csid_path_cfg *path_data;
1540 uint32_t val = 0;
1541
1542 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1543 csid_reg = csid_hw->csid_info->csid_reg;
1544 soc_info = &csid_hw->hw_info->soc_info;
1545
1546 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001547 CAM_ERR(CAM_ISP,
1548 "CSID:%d res type:%d res_id:%d Invalid state%d",
1549 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001550 res->res_type, res->res_id, res->res_state);
1551 return -EINVAL;
1552 }
1553
1554 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001555 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1556 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001557 res->res_id);
1558 return -EINVAL;
1559 }
1560
Harsh Shahf7136392017-08-29 12:42:52 -07001561 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001562
Harsh Shahf7136392017-08-29 12:42:52 -07001563 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001564 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1565 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1566 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1567 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1568 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1569 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1570 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1571 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1572 soc_info->reg_map[0].mem_base +
1573 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1574 }
1575 /* for slave mode, not need to resume for slave device */
1576
1577 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301578 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301579
1580 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1581 val |= CSID_PATH_INFO_INPUT_SOF;
1582 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1583 val |= CSID_PATH_INFO_INPUT_EOF;
1584
Jing Zhouff57d862017-03-21 00:54:25 -07001585 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1586 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1587
1588 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1589
1590 return 0;
1591}
1592
1593static int cam_ife_csid_disable_ipp_path(
1594 struct cam_ife_csid_hw *csid_hw,
1595 struct cam_isp_resource_node *res,
1596 enum cam_ife_csid_halt_cmd stop_cmd)
1597{
1598 int rc = 0;
1599 struct cam_ife_csid_reg_offset *csid_reg;
1600 struct cam_hw_soc_info *soc_info;
1601 struct cam_ife_csid_path_cfg *path_data;
1602 uint32_t val = 0;
1603
1604 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1605 csid_reg = csid_hw->csid_info->csid_reg;
1606 soc_info = &csid_hw->hw_info->soc_info;
1607
1608 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001609 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1610 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001611 return -EINVAL;
1612 }
1613
1614 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1615 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001616 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1617 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001618 res->res_id, res->res_state);
1619 return rc;
1620 }
1621
1622 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001623 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1624 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001625 res->res_state);
1626 return -EINVAL;
1627 }
1628
1629 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001630 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1631 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001632 return -EINVAL;
1633 }
1634
1635 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1636 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001637 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1638 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001639 return -EINVAL;
1640 }
1641
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001642 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001643 csid_hw->hw_intf->hw_idx, res->res_id);
1644
1645 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1646 /* configure Halt */
1647 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1648 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1649 val &= ~0x3;
1650 val |= stop_cmd;
1651 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1652 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1653 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1654 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1655 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1656
1657 /* For slave mode, halt command should take it from master */
1658
1659 /* Enable the EOF interrupt for resume at boundary case */
1660 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1661 init_completion(&csid_hw->csid_ipp_complete);
1662 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1663 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1664 val |= CSID_PATH_INFO_INPUT_EOF;
1665 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1666 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1667 } else {
1668 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001669 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001670 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1671 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1672 }
1673
1674 return rc;
1675}
1676
1677
1678static int cam_ife_csid_init_config_rdi_path(
1679 struct cam_ife_csid_hw *csid_hw,
1680 struct cam_isp_resource_node *res)
1681{
1682 int rc = 0;
1683 struct cam_ife_csid_path_cfg *path_data;
1684 struct cam_ife_csid_reg_offset *csid_reg;
1685 struct cam_hw_soc_info *soc_info;
1686 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1687
1688 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1689 csid_reg = csid_hw->csid_info->csid_reg;
1690 soc_info = &csid_hw->hw_info->soc_info;
1691
1692 id = res->res_id;
1693 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001694 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1695 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001696 return -EINVAL;
1697 }
1698
Harsh Shahf7136392017-08-29 12:42:52 -07001699 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1700 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001701 if (rc)
1702 return rc;
1703
Jing Zhoubb536a82017-05-18 15:20:38 -07001704 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001705 * RDI path config and enable the time stamp capture
1706 * Enable the measurement blocks
1707 */
1708 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1709 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1710 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1711 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1712 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301713 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001714 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301715 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001716 csid_reg->cmn_reg->crop_v_en_shift_val) |
1717 (1 << 2) | 3;
1718
1719 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1720 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1721
Jing Zhoudedc4762017-06-19 17:45:36 +05301722 /* select the post irq sub sample strobe for time stamp capture */
1723 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1724 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1725
Jing Zhouff57d862017-03-21 00:54:25 -07001726 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301727 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001728 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301729 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001730
1731 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1732 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301733 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1734 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001735
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301736 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001737 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301738 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001739
1740 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1741 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301742 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1743 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001744 }
1745 /* set frame drop pattern to 0 and period to 1 */
1746 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1747 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1748 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1749 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1750 /* set IRQ sum sabmple */
1751 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1752 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1753 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1754 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1755
1756 /* set pixel drop pattern to 0 and period to 1 */
1757 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1758 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1759 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1760 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1761 /* set line drop pattern to 0 and period to 1 */
1762 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1763 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1764 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1765 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1766
1767 /* Configure the halt mode */
1768 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1769 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1770
1771 /* Enable the RPP path */
1772 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1773 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1774 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001775
Jing Zhouff57d862017-03-21 00:54:25 -07001776 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1777 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1778
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301779 /* configure the rx packet capture based on csid debug set */
1780 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1781 val = ((1 <<
1782 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1783 (path_data->vc <<
1784 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1785
1786 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1787 val |= ((1 <<
1788 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1789 (path_data->dt <<
1790 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1791 (path_data->vc <<
1792 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1793
1794 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1795 val |= ((1 <<
1796 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1797 (path_data->dt <<
1798 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1799 (path_data->vc <<
1800 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1801 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1802 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1803
Jing Zhouff57d862017-03-21 00:54:25 -07001804 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1805
1806 return rc;
1807}
1808
1809static int cam_ife_csid_deinit_rdi_path(
1810 struct cam_ife_csid_hw *csid_hw,
1811 struct cam_isp_resource_node *res)
1812{
1813 int rc = 0;
1814 struct cam_ife_csid_reg_offset *csid_reg;
1815 struct cam_hw_soc_info *soc_info;
1816 uint32_t val = 0, id;
1817
1818 csid_reg = csid_hw->csid_info->csid_reg;
1819 soc_info = &csid_hw->hw_info->soc_info;
1820 id = res->res_id;
1821
1822 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1823 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1824 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001825 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1826 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001827 res->res_state);
1828 return -EINVAL;
1829 }
1830
1831 /* Disable the RDI path */
1832 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1833 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1834 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1835 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1836 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1837
1838 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1839 return rc;
1840}
1841
1842static int cam_ife_csid_enable_rdi_path(
1843 struct cam_ife_csid_hw *csid_hw,
1844 struct cam_isp_resource_node *res)
1845{
1846 struct cam_ife_csid_reg_offset *csid_reg;
1847 struct cam_hw_soc_info *soc_info;
1848 uint32_t id, val;
1849
1850 csid_reg = csid_hw->csid_info->csid_reg;
1851 soc_info = &csid_hw->hw_info->soc_info;
1852 id = res->res_id;
1853
1854 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1855 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1856 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001857 CAM_ERR(CAM_ISP,
1858 "CSID:%d invalid res type:%d res_id:%d state%d",
1859 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001860 res->res_type, res->res_id, res->res_state);
1861 return -EINVAL;
1862 }
1863
1864 /*resume at frame boundary */
1865 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1866 soc_info->reg_map[0].mem_base +
1867 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1868
1869 /* Enable the required RDI interrupts */
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301870 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
1871
1872 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1873 val |= CSID_PATH_INFO_INPUT_SOF;
1874 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1875 val |= CSID_PATH_INFO_INPUT_EOF;
1876
Jing Zhouff57d862017-03-21 00:54:25 -07001877 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1878 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1879
1880 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1881
1882 return 0;
1883}
1884
1885
1886static int cam_ife_csid_disable_rdi_path(
1887 struct cam_ife_csid_hw *csid_hw,
1888 struct cam_isp_resource_node *res,
1889 enum cam_ife_csid_halt_cmd stop_cmd)
1890{
1891 int rc = 0;
1892 struct cam_ife_csid_reg_offset *csid_reg;
1893 struct cam_hw_soc_info *soc_info;
1894 uint32_t val = 0, id;
1895
1896 csid_reg = csid_hw->csid_info->csid_reg;
1897 soc_info = &csid_hw->hw_info->soc_info;
1898 id = res->res_id;
1899
1900 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1901 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001902 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1903 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001904 return -EINVAL;
1905 }
1906
1907 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1908 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001909 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1910 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001911 res->res_id, res->res_state);
1912 return rc;
1913 }
1914
1915 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001916 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1917 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001918 res->res_state);
1919 return -EINVAL;
1920 }
1921
1922 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1923 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001924 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1925 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001926 return -EINVAL;
1927 }
1928
1929
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001930 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001931 csid_hw->hw_intf->hw_idx, res->res_id);
1932
1933 init_completion(&csid_hw->csid_rdin_complete[id]);
1934
1935 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1936 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1937 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1938 val |= CSID_PATH_INFO_INPUT_EOF;
1939 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1940 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1941 } else {
1942 val &= ~(CSID_PATH_INFO_RST_DONE |
1943 CSID_PATH_ERROR_FIFO_OVERFLOW);
1944 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1945 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1946 }
1947
1948 /*Halt the RDI path */
1949 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1950 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1951
1952 return rc;
1953}
1954
1955static int cam_ife_csid_get_time_stamp(
1956 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1957{
1958 struct cam_csid_get_time_stamp_args *time_stamp;
1959 struct cam_isp_resource_node *res;
1960 struct cam_ife_csid_reg_offset *csid_reg;
1961 struct cam_hw_soc_info *soc_info;
1962 uint32_t time_32, id;
1963
1964 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1965 res = time_stamp->node_res;
1966 csid_reg = csid_hw->csid_info->csid_reg;
1967 soc_info = &csid_hw->hw_info->soc_info;
1968
1969 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1970 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001971 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1972 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001973 res->res_id);
1974 return -EINVAL;
1975 }
1976
1977 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001978 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1979 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001980 csid_hw->hw_info->hw_state);
1981 return -EINVAL;
1982 }
1983
1984 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1985 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1986 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1987 time_stamp->time_stamp_val = time_32;
1988 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1989 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1990 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1991 time_stamp->time_stamp_val |= time_32;
1992 } else {
1993 id = res->res_id;
1994 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1995 csid_reg->rdi_reg[id]->
1996 csid_rdi_timestamp_curr1_sof_addr);
1997 time_stamp->time_stamp_val = time_32;
1998 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1999
2000 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2001 csid_reg->rdi_reg[id]->
2002 csid_rdi_timestamp_curr0_sof_addr);
2003 time_stamp->time_stamp_val |= time_32;
2004 }
2005
Harsh Shah3ba2a4f2017-10-23 16:20:44 -07002006 time_stamp->time_stamp_val = mul_u64_u32_div(
2007 time_stamp->time_stamp_val,
2008 CAM_IFE_CSID_QTIMER_MUL_FACTOR,
2009 CAM_IFE_CSID_QTIMER_DIV_FACTOR);
2010
Jing Zhouff57d862017-03-21 00:54:25 -07002011 return 0;
2012}
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302013
2014static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw,
2015 void *cmd_args)
2016{
2017 uint32_t *csid_debug;
2018
2019 csid_debug = (uint32_t *) cmd_args;
2020 csid_hw->csid_debug = *csid_debug;
2021 CAM_DBG(CAM_ISP, "CSID:%d set csid debug value:%d",
2022 csid_hw->hw_intf->hw_idx, csid_hw->csid_debug);
2023
2024 return 0;
2025}
2026
Jing Zhouff57d862017-03-21 00:54:25 -07002027static int cam_ife_csid_res_wait_for_halt(
2028 struct cam_ife_csid_hw *csid_hw,
2029 struct cam_isp_resource_node *res)
2030{
2031 int rc = 0;
2032 struct cam_ife_csid_reg_offset *csid_reg;
2033 struct cam_hw_soc_info *soc_info;
2034
2035 struct completion *complete;
2036 uint32_t val = 0, id;
2037
2038 csid_reg = csid_hw->csid_info->csid_reg;
2039 soc_info = &csid_hw->hw_info->soc_info;
2040
2041 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002042 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
2043 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002044 return -EINVAL;
2045 }
2046
2047 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
2048 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002049 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
2050 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002051 res->res_id, res->res_state);
2052 return rc;
2053 }
2054
2055 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002056 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
2057 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07002058 res->res_state);
2059 return -EINVAL;
2060 }
2061
2062 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2063 complete = &csid_hw->csid_ipp_complete;
2064 else
2065 complete = &csid_hw->csid_rdin_complete[res->res_id];
2066
2067 rc = wait_for_completion_timeout(complete,
2068 msecs_to_jiffies(IFE_CSID_TIMEOUT));
2069 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002070 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
2071 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002072 res->res_id, rc);
2073 if (rc == 0)
2074 /* continue even have timeout */
2075 rc = -ETIMEDOUT;
2076 }
2077
2078 /* Disable the interrupt */
2079 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
2080 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2081 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2082 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2083 CSID_PATH_ERROR_FIFO_OVERFLOW);
2084 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2085 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2086 } else {
2087 id = res->res_id;
2088 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2089 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2090 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2091 CSID_PATH_ERROR_FIFO_OVERFLOW);
2092 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2093 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2094 }
2095 /* set state to init HW */
2096 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
2097 return rc;
2098}
2099
2100static int cam_ife_csid_get_hw_caps(void *hw_priv,
2101 void *get_hw_cap_args, uint32_t arg_size)
2102{
2103 int rc = 0;
2104 struct cam_ife_csid_hw_caps *hw_caps;
2105 struct cam_ife_csid_hw *csid_hw;
2106 struct cam_hw_info *csid_hw_info;
2107 struct cam_ife_csid_reg_offset *csid_reg;
2108
2109 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002110 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002111 return -EINVAL;
2112 }
2113
2114 csid_hw_info = (struct cam_hw_info *)hw_priv;
2115 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2116 csid_reg = csid_hw->csid_info->csid_reg;
2117 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
2118
2119 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
2120 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
2121 hw_caps->major_version = csid_reg->cmn_reg->major_version;
2122 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
2123 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
2124
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002125 CAM_DBG(CAM_ISP,
2126 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
2127 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07002128 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
2129 hw_caps->version_incr);
2130
2131 return rc;
2132}
2133
2134static int cam_ife_csid_reset(void *hw_priv,
2135 void *reset_args, uint32_t arg_size)
2136{
2137 struct cam_ife_csid_hw *csid_hw;
2138 struct cam_hw_info *csid_hw_info;
2139 struct cam_csid_reset_cfg_args *reset;
2140 int rc = 0;
2141
2142 if (!hw_priv || !reset_args || (arg_size !=
2143 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002144 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002145 return -EINVAL;
2146 }
2147
2148 csid_hw_info = (struct cam_hw_info *)hw_priv;
2149 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2150 reset = (struct cam_csid_reset_cfg_args *)reset_args;
2151
2152 switch (reset->reset_type) {
2153 case CAM_IFE_CSID_RESET_GLOBAL:
2154 rc = cam_ife_csid_global_reset(csid_hw);
2155 break;
2156 case CAM_IFE_CSID_RESET_PATH:
2157 rc = cam_ife_csid_path_reset(csid_hw, reset);
2158 break;
2159 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002160 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
2161 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002162 rc = -EINVAL;
2163 break;
2164 }
2165
2166 return rc;
2167}
2168
2169static int cam_ife_csid_reserve(void *hw_priv,
2170 void *reserve_args, uint32_t arg_size)
2171{
2172 int rc = 0;
2173 struct cam_ife_csid_hw *csid_hw;
2174 struct cam_hw_info *csid_hw_info;
2175 struct cam_csid_hw_reserve_resource_args *reserv;
2176
2177 if (!hw_priv || !reserve_args || (arg_size !=
2178 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002179 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002180 return -EINVAL;
2181 }
2182
2183 csid_hw_info = (struct cam_hw_info *)hw_priv;
2184 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2185 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2186
2187 mutex_lock(&csid_hw->hw_info->hw_mutex);
2188 switch (reserv->res_type) {
2189 case CAM_ISP_RESOURCE_CID:
2190 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2191 break;
2192 case CAM_ISP_RESOURCE_PIX_PATH:
2193 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2194 break;
2195 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002196 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2197 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002198 rc = -EINVAL;
2199 break;
2200 }
2201 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2202 return rc;
2203}
2204
2205static int cam_ife_csid_release(void *hw_priv,
2206 void *release_args, uint32_t arg_size)
2207{
2208 int rc = 0;
2209 struct cam_ife_csid_hw *csid_hw;
2210 struct cam_hw_info *csid_hw_info;
2211 struct cam_isp_resource_node *res;
2212 struct cam_ife_csid_cid_data *cid_data;
2213
2214 if (!hw_priv || !release_args ||
2215 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002216 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002217 return -EINVAL;
2218 }
2219
2220 csid_hw_info = (struct cam_hw_info *)hw_priv;
2221 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2222 res = (struct cam_isp_resource_node *)release_args;
2223
2224 mutex_lock(&csid_hw->hw_info->hw_mutex);
2225 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2226 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2227 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2228 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002229 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2230 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002231 res->res_id);
2232 rc = -EINVAL;
2233 goto end;
2234 }
2235
2236 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002237 CAM_DBG(CAM_ISP,
2238 "CSID:%d res type:%d Res %d in released state",
2239 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002240 res->res_type, res->res_id);
2241 goto end;
2242 }
2243
2244 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2245 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002246 CAM_DBG(CAM_ISP,
2247 "CSID:%d res type:%d Res id:%d invalid state:%d",
2248 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002249 res->res_type, res->res_id, res->res_state);
2250 rc = -EINVAL;
2251 goto end;
2252 }
2253
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002254 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2255 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002256
2257 switch (res->res_type) {
2258 case CAM_ISP_RESOURCE_CID:
2259 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2260 if (cid_data->cnt)
2261 cid_data->cnt--;
2262
2263 if (!cid_data->cnt)
2264 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2265
2266 if (csid_hw->csi2_reserve_cnt)
2267 csid_hw->csi2_reserve_cnt--;
2268
2269 if (!csid_hw->csi2_reserve_cnt)
2270 memset(&csid_hw->csi2_rx_cfg, 0,
2271 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2272
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002273 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2274 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002275 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2276
2277 break;
2278 case CAM_ISP_RESOURCE_PIX_PATH:
2279 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2280 break;
2281 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002282 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2283 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002284 res->res_id);
2285 rc = -EINVAL;
2286 break;
2287 }
2288
2289end:
2290 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2291 return rc;
2292}
2293
2294static int cam_ife_csid_init_hw(void *hw_priv,
2295 void *init_args, uint32_t arg_size)
2296{
2297 int rc = 0;
2298 struct cam_ife_csid_hw *csid_hw;
2299 struct cam_hw_info *csid_hw_info;
2300 struct cam_isp_resource_node *res;
2301 struct cam_ife_csid_reg_offset *csid_reg;
2302
2303 if (!hw_priv || !init_args ||
2304 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002305 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002306 return -EINVAL;
2307 }
2308
2309 csid_hw_info = (struct cam_hw_info *)hw_priv;
2310 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2311 res = (struct cam_isp_resource_node *)init_args;
2312 csid_reg = csid_hw->csid_info->csid_reg;
2313
2314 mutex_lock(&csid_hw->hw_info->hw_mutex);
2315 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2316 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2317 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2318 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002319 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2320 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002321 res->res_id);
2322 rc = -EINVAL;
2323 goto end;
2324 }
2325
2326
2327 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2328 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002329 CAM_ERR(CAM_ISP,
2330 "CSID:%d res type:%d res_id:%dInvalid state %d",
2331 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002332 res->res_type, res->res_id, res->res_state);
2333 rc = -EINVAL;
2334 goto end;
2335 }
2336
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002337 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002338 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2339
2340
2341 /* Initialize the csid hardware */
2342 rc = cam_ife_csid_enable_hw(csid_hw);
2343 if (rc)
2344 goto end;
2345
2346 switch (res->res_type) {
2347 case CAM_ISP_RESOURCE_CID:
2348 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2349 break;
2350 case CAM_ISP_RESOURCE_PIX_PATH:
2351 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2352 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2353 else
2354 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2355
2356 break;
2357 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002358 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2359 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002360 res->res_type);
2361 break;
2362 }
2363
2364 if (rc)
2365 cam_ife_csid_disable_hw(csid_hw);
2366end:
2367 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2368 return rc;
2369}
2370
2371static int cam_ife_csid_deinit_hw(void *hw_priv,
2372 void *deinit_args, uint32_t arg_size)
2373{
2374 int rc = 0;
2375 struct cam_ife_csid_hw *csid_hw;
2376 struct cam_hw_info *csid_hw_info;
2377 struct cam_isp_resource_node *res;
2378
2379 if (!hw_priv || !deinit_args ||
2380 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002381 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002382 return -EINVAL;
2383 }
2384
2385 res = (struct cam_isp_resource_node *)deinit_args;
2386 csid_hw_info = (struct cam_hw_info *)hw_priv;
2387 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2388
2389 mutex_lock(&csid_hw->hw_info->hw_mutex);
2390 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002391 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2392 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002393 res->res_id);
2394 goto end;
2395 }
2396
2397 switch (res->res_type) {
2398 case CAM_ISP_RESOURCE_CID:
2399 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2400 break;
2401 case CAM_ISP_RESOURCE_PIX_PATH:
2402 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2403 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2404 else
2405 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2406
2407 break;
2408 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002409 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2410 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002411 res->res_type);
2412 goto end;
2413 }
2414
2415 /* Disable CSID HW */
2416 cam_ife_csid_disable_hw(csid_hw);
2417
2418end:
2419 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2420 return rc;
2421}
2422
2423static int cam_ife_csid_start(void *hw_priv, void *start_args,
2424 uint32_t arg_size)
2425{
2426 int rc = 0;
2427 struct cam_ife_csid_hw *csid_hw;
2428 struct cam_hw_info *csid_hw_info;
2429 struct cam_isp_resource_node *res;
2430 struct cam_ife_csid_reg_offset *csid_reg;
2431
2432 if (!hw_priv || !start_args ||
2433 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002434 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002435 return -EINVAL;
2436 }
2437
2438 csid_hw_info = (struct cam_hw_info *)hw_priv;
2439 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2440 res = (struct cam_isp_resource_node *)start_args;
2441 csid_reg = csid_hw->csid_info->csid_reg;
2442
Jing Zhouff57d862017-03-21 00:54:25 -07002443 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2444 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2445 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2446 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002447 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2448 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002449 res->res_id);
2450 rc = -EINVAL;
2451 goto end;
2452 }
2453
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002454 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002455 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2456
2457 switch (res->res_type) {
2458 case CAM_ISP_RESOURCE_CID:
2459 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2460 rc = cam_ife_csid_tpg_start(csid_hw, res);
2461 break;
2462 case CAM_ISP_RESOURCE_PIX_PATH:
2463 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2464 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2465 else
2466 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2467 break;
2468 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002469 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2470 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002471 res->res_type);
2472 break;
2473 }
2474end:
Jing Zhouff57d862017-03-21 00:54:25 -07002475 return rc;
2476}
2477
2478static int cam_ife_csid_stop(void *hw_priv,
2479 void *stop_args, uint32_t arg_size)
2480{
2481 int rc = 0;
2482 struct cam_ife_csid_hw *csid_hw;
2483 struct cam_hw_info *csid_hw_info;
2484 struct cam_isp_resource_node *res;
2485 struct cam_csid_hw_stop_args *csid_stop;
2486 uint32_t i;
2487
2488 if (!hw_priv || !stop_args ||
2489 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002490 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002491 return -EINVAL;
2492 }
2493 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2494 csid_hw_info = (struct cam_hw_info *)hw_priv;
2495 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2496
Jing Zhouff57d862017-03-21 00:54:25 -07002497 /* Stop the resource first */
2498 for (i = 0; i < csid_stop->num_res; i++) {
2499 res = csid_stop->node_res[i];
2500 switch (res->res_type) {
2501 case CAM_ISP_RESOURCE_CID:
2502 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2503 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2504 break;
2505 case CAM_ISP_RESOURCE_PIX_PATH:
2506 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2507 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2508 res, csid_stop->stop_cmd);
2509 else
2510 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2511 res, csid_stop->stop_cmd);
2512
2513 break;
2514 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002515 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2516 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002517 res->res_type);
2518 break;
2519 }
2520 }
2521
2522 /*wait for the path to halt */
2523 for (i = 0; i < csid_stop->num_res; i++) {
2524 res = csid_stop->node_res[i];
2525 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2526 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2527 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302528 else
2529 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002530 }
2531
Jing Zhouff57d862017-03-21 00:54:25 -07002532 return rc;
2533
2534}
2535
2536static int cam_ife_csid_read(void *hw_priv,
2537 void *read_args, uint32_t arg_size)
2538{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002539 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002540
2541 return -EINVAL;
2542}
2543
2544static int cam_ife_csid_write(void *hw_priv,
2545 void *write_args, uint32_t arg_size)
2546{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002547 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002548 return -EINVAL;
2549}
2550
2551static int cam_ife_csid_process_cmd(void *hw_priv,
2552 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2553{
2554 int rc = 0;
2555 struct cam_ife_csid_hw *csid_hw;
2556 struct cam_hw_info *csid_hw_info;
2557
2558 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002559 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002560 return -EINVAL;
2561 }
2562
2563 csid_hw_info = (struct cam_hw_info *)hw_priv;
2564 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2565
Jing Zhouff57d862017-03-21 00:54:25 -07002566 switch (cmd_type) {
2567 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2568 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2569 break;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302570 case CAM_IFE_CSID_SET_CSID_DEBUG:
2571 rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args);
2572 break;
Jing Zhouff57d862017-03-21 00:54:25 -07002573 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002574 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2575 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002576 rc = -EINVAL;
2577 break;
2578 }
Jing Zhouff57d862017-03-21 00:54:25 -07002579
2580 return rc;
2581
2582}
2583
2584irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2585{
2586 struct cam_ife_csid_hw *csid_hw;
2587 struct cam_hw_soc_info *soc_info;
2588 struct cam_ife_csid_reg_offset *csid_reg;
Harsh Shah1b8eb232017-10-09 19:20:52 -07002589 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
2590 uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
Harsh Shahf7136392017-08-29 12:42:52 -07002591 uint32_t val;
Jing Zhouff57d862017-03-21 00:54:25 -07002592
2593 csid_hw = (struct cam_ife_csid_hw *)data;
2594
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002595 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002596
2597 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002598 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002599 return IRQ_HANDLED;
2600 }
2601
2602 csid_reg = csid_hw->csid_info->csid_reg;
2603 soc_info = &csid_hw->hw_info->soc_info;
2604
2605 /* read */
2606 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2607 csid_reg->cmn_reg->csid_top_irq_status_addr);
2608
2609 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2610 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2611
2612 if (csid_reg->cmn_reg->no_pix)
2613 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2614 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2615
2616
2617 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2618 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2619 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2620
2621 /* clear */
2622 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2623 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2624 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2625 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2626 if (csid_reg->cmn_reg->no_pix)
2627 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2628 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2629
2630 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2631 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2632 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2633 }
2634 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2635 csid_reg->cmn_reg->csid_irq_cmd_addr);
2636
Harsh Shah1b8eb232017-10-09 19:20:52 -07002637 CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002638 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2639 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Harsh Shah1b8eb232017-10-09 19:20:52 -07002640 CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]);
2641 CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]);
2642 CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]);
Jing Zhouff57d862017-03-21 00:54:25 -07002643
2644 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002645 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002646 complete(&csid_hw->csid_top_complete);
2647 return IRQ_HANDLED;
2648 }
2649
2650
2651 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002652 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002653 complete(&csid_hw->csid_csi2_complete);
2654 }
2655
2656 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002657 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002658 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002659 }
2660 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002661 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002662 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002663 }
2664 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002665 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002666 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002667 }
2668 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002669 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002670 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002671 }
2672 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002673 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002674 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002675 }
2676 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002677 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_EOT_RECEPTION",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002678 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002679 }
2680 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002681 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_SOT_RECEPTION",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002682 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002683 }
2684 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Harsh Shah1b8eb232017-10-09 19:20:52 -07002685 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
2686 csid_hw->hw_intf->hw_idx);
2687 }
2688 if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
2689 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
2690 csid_hw->hw_intf->hw_idx);
2691 }
2692 if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
2693 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
2694 csid_hw->hw_intf->hw_idx);
2695 }
2696 if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
2697 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
2698 csid_hw->hw_intf->hw_idx);
2699 }
2700 if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
2701 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_STREAM_UNDERFLOW",
2702 csid_hw->hw_intf->hw_idx);
2703 }
2704 if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
2705 CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002706 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002707 }
2708
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302709 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
2710 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
2711 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_EOT_CAPTURED",
2712 csid_hw->hw_intf->hw_idx);
2713 }
2714 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED) {
2715 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_EOT_CAPTURED",
2716 csid_hw->hw_intf->hw_idx);
2717 }
2718 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED) {
2719 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_EOT_CAPTURED",
2720 csid_hw->hw_intf->hw_idx);
2721 }
2722 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED) {
2723 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_EOT_CAPTURED",
2724 csid_hw->hw_intf->hw_idx);
2725 }
2726 }
2727
2728 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) {
2729 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED) {
2730 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_SOT_CAPTURED",
2731 csid_hw->hw_intf->hw_idx);
2732 }
2733 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED) {
2734 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_SOT_CAPTURED",
2735 csid_hw->hw_intf->hw_idx);
2736 }
2737 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED) {
2738 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_SOT_CAPTURED",
2739 csid_hw->hw_intf->hw_idx);
2740 }
2741 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED) {
2742 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_SOT_CAPTURED",
2743 csid_hw->hw_intf->hw_idx);
2744 }
2745 }
2746
2747 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) &&
2748 (irq_status_rx & CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED)) {
2749 CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
2750 csid_hw->hw_intf->hw_idx);
2751 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2752 csid_reg->csi2_reg->
2753 csid_csi2_rx_captured_long_pkt_0_addr);
2754 CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
2755 csid_hw->hw_intf->hw_idx,
2756 (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
2757 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2758 csid_reg->csi2_reg->
2759 csid_csi2_rx_captured_long_pkt_1_addr);
2760 CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
2761 csid_hw->hw_intf->hw_idx, val);
2762 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2763 csid_reg->csi2_reg->
2764 csid_csi2_rx_captured_long_pkt_ftr_addr);
2765 CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
2766 csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
2767 }
2768 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) &&
2769 (irq_status_rx & CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED)) {
2770 CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
2771 csid_hw->hw_intf->hw_idx);
2772 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2773 csid_reg->csi2_reg->
2774 csid_csi2_rx_captured_short_pkt_0_addr);
2775 CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
2776 csid_hw->hw_intf->hw_idx,
2777 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2778 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2779 csid_reg->csi2_reg->
2780 csid_csi2_rx_captured_short_pkt_1_addr);
2781 CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d", val);
2782 }
2783
2784 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
2785 (irq_status_rx & CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED)) {
2786 CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
2787 csid_hw->hw_intf->hw_idx);
2788 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2789 csid_reg->csi2_reg->
2790 csid_csi2_rx_captured_cphy_pkt_hdr_addr);
2791 CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
2792 csid_hw->hw_intf->hw_idx,
2793 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2794 }
2795
Jing Zhouff57d862017-03-21 00:54:25 -07002796 /*read the IPP errors */
2797 if (csid_reg->cmn_reg->no_pix) {
2798 /* IPP reset done bit */
2799 if (irq_status_ipp &
2800 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002801 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002802 complete(&csid_hw->csid_ipp_complete);
2803 }
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302804
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302805 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
2806 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2807 CAM_ERR(CAM_ISP, "CSID:%d IPP SOF received",
2808 csid_hw->hw_intf->hw_idx);
2809
2810 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
2811 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2812 CAM_ERR(CAM_ISP, "CSID:%d IPP EOF received",
2813 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002814
2815 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2816 complete(&csid_hw->csid_ipp_complete);
2817
2818 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002819 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002820 csid_hw->hw_intf->hw_idx);
2821 /*Stop IPP path immediately */
2822 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2823 soc_info->reg_map[0].mem_base +
2824 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2825 }
2826 }
2827
2828 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2829 if (irq_status_rdi[i] &
2830 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302831 CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002832 complete(&csid_hw->csid_rdin_complete[i]);
2833 }
2834
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302835 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
2836 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2837 CAM_ERR(CAM_ISP, "CSID RDI:%d SOF received", i);
2838
2839 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) &&
2840 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2841 CAM_ERR(CAM_ISP, "CSID RDI:%d EOF received", i);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302842
Jing Zhouff57d862017-03-21 00:54:25 -07002843 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2844 complete(&csid_hw->csid_rdin_complete[i]);
2845
2846 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002847 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002848 csid_hw->hw_intf->hw_idx);
2849 /*Stop RDI path immediately */
2850 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2851 soc_info->reg_map[0].mem_base +
2852 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2853 }
2854 }
2855
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002856 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002857 return IRQ_HANDLED;
2858}
2859
2860int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2861 uint32_t csid_idx)
2862{
2863 int rc = -EINVAL;
2864 uint32_t i;
2865 struct cam_ife_csid_path_cfg *path_data;
2866 struct cam_ife_csid_cid_data *cid_data;
2867 struct cam_hw_info *csid_hw_info;
2868 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2869
2870 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002871 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002872 return rc;
2873 }
2874
2875 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2876 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2877
2878 ife_csid_hw->hw_intf = csid_hw_intf;
2879 ife_csid_hw->hw_info = csid_hw_info;
2880
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002881 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002882 ife_csid_hw->hw_intf->hw_type, csid_idx);
2883
2884
2885 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2886 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2887 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2888 init_completion(&ife_csid_hw->hw_info->hw_complete);
2889
2890 init_completion(&ife_csid_hw->csid_top_complete);
2891 init_completion(&ife_csid_hw->csid_csi2_complete);
2892 init_completion(&ife_csid_hw->csid_ipp_complete);
2893 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2894 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2895
2896
2897 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2898 cam_ife_csid_irq, ife_csid_hw);
2899 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002900 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002901 goto err;
2902 }
2903
2904 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2905 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2906 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2907 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2908 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2909 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2910 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2911 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2912 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2913 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2914 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2915
2916 /*Initialize the CID resoure */
2917 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2918 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2919 ife_csid_hw->cid_res[i].res_id = i;
2920 ife_csid_hw->cid_res[i].res_state =
2921 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2922 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2923
2924 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2925 GFP_KERNEL);
2926 if (!cid_data) {
2927 rc = -ENOMEM;
2928 goto err;
2929 }
2930 ife_csid_hw->cid_res[i].res_priv = cid_data;
2931 }
2932
2933 /* Initialize the IPP resources */
2934 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2935 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2936 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2937 ife_csid_hw->ipp_res.res_state =
2938 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2939 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2940 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2941 GFP_KERNEL);
2942 if (!path_data) {
2943 rc = -ENOMEM;
2944 goto err;
2945 }
2946 ife_csid_hw->ipp_res.res_priv = path_data;
2947 }
2948
2949 /* Initialize the RDI resource */
2950 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2951 i++) {
2952 /* res type is from RDI 0 to RDI3 */
2953 ife_csid_hw->rdi_res[i].res_type =
2954 CAM_ISP_RESOURCE_PIX_PATH;
2955 ife_csid_hw->rdi_res[i].res_id = i;
2956 ife_csid_hw->rdi_res[i].res_state =
2957 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2958 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2959
2960 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2961 GFP_KERNEL);
2962 if (!path_data) {
2963 rc = -ENOMEM;
2964 goto err;
2965 }
2966 ife_csid_hw->rdi_res[i].res_priv = path_data;
2967 }
2968
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302969 ife_csid_hw->csid_debug = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07002970 return 0;
2971err:
2972 if (rc) {
2973 kfree(ife_csid_hw->ipp_res.res_priv);
2974 for (i = 0; i <
2975 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2976 kfree(ife_csid_hw->rdi_res[i].res_priv);
2977
2978 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2979 kfree(ife_csid_hw->cid_res[i].res_priv);
2980
2981 }
2982
2983 return rc;
2984}
2985
2986
2987int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2988{
2989 int rc = -EINVAL;
2990 uint32_t i;
2991
2992 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002993 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002994 return rc;
2995 }
2996
2997 /* release the privdate data memory from resources */
2998 kfree(ife_csid_hw->ipp_res.res_priv);
2999 for (i = 0; i <
3000 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
3001 i++) {
3002 kfree(ife_csid_hw->rdi_res[i].res_priv);
3003 }
3004 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
3005 kfree(ife_csid_hw->cid_res[i].res_priv);
3006
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05303007 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07003008
3009 return 0;
3010}