blob: 9895e33d4b9f8bb3281229ad1ea0bbfc436689ec [file] [log] [blame]
Jing Zhouff57d862017-03-21 00:54:25 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/iopoll.h>
14#include <linux/slab.h>
15#include <uapi/media/cam_isp.h>
16#include <uapi/media/cam_defs.h>
17
18#include "cam_ife_csid_core.h"
19#include "cam_isp_hw.h"
20#include "cam_soc_util.h"
21#include "cam_io_util.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070022#include "cam_debug_util.h"
Jing Zhouff57d862017-03-21 00:54:25 -070023
24/* Timeout value in msec */
25#define IFE_CSID_TIMEOUT 1000
26
27/* TPG VC/DT values */
28#define CAM_IFE_CSID_TPG_VC_VAL 0xA
29#define CAM_IFE_CSID_TPG_DT_VAL 0x2B
30
31/* Timeout values in usec */
32#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
33#define CAM_IFE_CSID_TIMEOUT_ALL_US 1000000
34
35static int cam_ife_csid_is_ipp_format_supported(
Harsh Shahf7136392017-08-29 12:42:52 -070036 uint32_t in_format)
Jing Zhouff57d862017-03-21 00:54:25 -070037{
38 int rc = -EINVAL;
39
Harsh Shahf7136392017-08-29 12:42:52 -070040 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070041 case CAM_FORMAT_MIPI_RAW_6:
42 case CAM_FORMAT_MIPI_RAW_8:
43 case CAM_FORMAT_MIPI_RAW_10:
44 case CAM_FORMAT_MIPI_RAW_12:
45 case CAM_FORMAT_MIPI_RAW_14:
46 case CAM_FORMAT_MIPI_RAW_16:
47 case CAM_FORMAT_MIPI_RAW_20:
48 case CAM_FORMAT_DPCM_10_6_10:
49 case CAM_FORMAT_DPCM_10_8_10:
50 case CAM_FORMAT_DPCM_12_6_12:
51 case CAM_FORMAT_DPCM_12_8_12:
52 case CAM_FORMAT_DPCM_14_8_14:
53 case CAM_FORMAT_DPCM_14_10_14:
54 rc = 0;
55 break;
56 default:
57 break;
58 }
59 return rc;
60}
61
Harsh Shahf7136392017-08-29 12:42:52 -070062static int cam_ife_csid_get_format_rdi(
63 uint32_t in_format, uint32_t out_format,
64 uint32_t *decode_fmt, uint32_t *plain_fmt)
Jing Zhouff57d862017-03-21 00:54:25 -070065{
66 int rc = 0;
67
Harsh Shahf7136392017-08-29 12:42:52 -070068 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070069 case CAM_FORMAT_MIPI_RAW_6:
Harsh Shahf7136392017-08-29 12:42:52 -070070 switch (out_format) {
71 case CAM_FORMAT_MIPI_RAW_6:
72 *decode_fmt = 0xf;
73 break;
74 case CAM_FORMAT_PLAIN8:
75 *decode_fmt = 0x0;
76 *plain_fmt = 0x0;
77 break;
78 default:
79 rc = -EINVAL;
80 break;
81 }
Jing Zhouff57d862017-03-21 00:54:25 -070082 break;
83 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahf7136392017-08-29 12:42:52 -070084 switch (out_format) {
85 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahea34b602017-09-29 11:42:45 -070086 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -070087 *decode_fmt = 0xf;
88 break;
89 case CAM_FORMAT_PLAIN8:
90 *decode_fmt = 0x1;
91 *plain_fmt = 0x0;
92 break;
93 default:
94 rc = -EINVAL;
95 break;
96 }
Jing Zhouff57d862017-03-21 00:54:25 -070097 break;
98 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -070099 switch (out_format) {
100 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahea34b602017-09-29 11:42:45 -0700101 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700102 *decode_fmt = 0xf;
103 break;
104 case CAM_FORMAT_PLAIN16_10:
105 *decode_fmt = 0x2;
106 *plain_fmt = 0x1;
107 break;
108 default:
109 rc = -EINVAL;
110 break;
111 }
Jing Zhouff57d862017-03-21 00:54:25 -0700112 break;
113 case CAM_FORMAT_MIPI_RAW_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700114 switch (out_format) {
115 case CAM_FORMAT_MIPI_RAW_12:
116 *decode_fmt = 0xf;
117 break;
118 case CAM_FORMAT_PLAIN16_12:
119 *decode_fmt = 0x3;
120 *plain_fmt = 0x1;
121 break;
122 default:
123 rc = -EINVAL;
124 break;
125 }
Jing Zhouff57d862017-03-21 00:54:25 -0700126 break;
127 case CAM_FORMAT_MIPI_RAW_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700128 switch (out_format) {
129 case CAM_FORMAT_MIPI_RAW_14:
130 *decode_fmt = 0xf;
131 break;
132 case CAM_FORMAT_PLAIN16_14:
133 *decode_fmt = 0x4;
134 *plain_fmt = 0x1;
135 break;
136 default:
137 rc = -EINVAL;
138 break;
139 }
Jing Zhouff57d862017-03-21 00:54:25 -0700140 break;
141 case CAM_FORMAT_MIPI_RAW_16:
Harsh Shahf7136392017-08-29 12:42:52 -0700142 switch (out_format) {
143 case CAM_FORMAT_MIPI_RAW_16:
144 *decode_fmt = 0xf;
145 break;
146 case CAM_FORMAT_PLAIN16_16:
147 *decode_fmt = 0x5;
148 *plain_fmt = 0x1;
149 break;
150 default:
151 rc = -EINVAL;
152 break;
153 }
Jing Zhouff57d862017-03-21 00:54:25 -0700154 break;
155 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahf7136392017-08-29 12:42:52 -0700156 switch (out_format) {
157 case CAM_FORMAT_MIPI_RAW_20:
158 *decode_fmt = 0xf;
159 break;
160 case CAM_FORMAT_PLAIN32_20:
161 *decode_fmt = 0x6;
162 *plain_fmt = 0x2;
163 break;
164 default:
165 rc = -EINVAL;
166 break;
167 }
Jing Zhouff57d862017-03-21 00:54:25 -0700168 break;
169 case CAM_FORMAT_DPCM_10_6_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700170 *decode_fmt = 0x7;
171 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700172 break;
173 case CAM_FORMAT_DPCM_10_8_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700174 *decode_fmt = 0x8;
175 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700176 break;
177 case CAM_FORMAT_DPCM_12_6_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700178 *decode_fmt = 0x9;
179 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700180 break;
181 case CAM_FORMAT_DPCM_12_8_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700182 *decode_fmt = 0xA;
183 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700184 break;
185 case CAM_FORMAT_DPCM_14_8_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700186 *decode_fmt = 0xB;
187 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700188 break;
189 case CAM_FORMAT_DPCM_14_10_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700190 *decode_fmt = 0xC;
191 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700192 break;
193 default:
Harsh Shahf7136392017-08-29 12:42:52 -0700194 rc = -EINVAL;
195 break;
196 }
197
198 if (rc)
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530199 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d",
Harsh Shahf7136392017-08-29 12:42:52 -0700200 in_format, out_format);
201
202 return rc;
203}
204
205static int cam_ife_csid_get_format_ipp(
206 uint32_t in_format,
207 uint32_t *decode_fmt, uint32_t *plain_fmt)
208{
209 int rc = 0;
210
211 CAM_DBG(CAM_ISP, "input format:%d",
212 in_format);
213
214 switch (in_format) {
215 case CAM_FORMAT_MIPI_RAW_6:
216 *decode_fmt = 0;
217 *plain_fmt = 0;
218 break;
219 case CAM_FORMAT_MIPI_RAW_8:
220 *decode_fmt = 0x1;
221 *plain_fmt = 0;
222 break;
223 case CAM_FORMAT_MIPI_RAW_10:
224 *decode_fmt = 0x2;
225 *plain_fmt = 0x1;
226 break;
227 case CAM_FORMAT_MIPI_RAW_12:
228 *decode_fmt = 0x3;
229 *plain_fmt = 0x1;
230 break;
231 case CAM_FORMAT_MIPI_RAW_14:
232 *decode_fmt = 0x4;
233 *plain_fmt = 0x1;
234 break;
235 case CAM_FORMAT_MIPI_RAW_16:
236 *decode_fmt = 0x5;
237 *plain_fmt = 0x1;
238 break;
239 case CAM_FORMAT_MIPI_RAW_20:
240 *decode_fmt = 0x6;
241 *plain_fmt = 0x2;
242 break;
243 case CAM_FORMAT_DPCM_10_6_10:
244 *decode_fmt = 0x7;
245 *plain_fmt = 0x1;
246 break;
247 case CAM_FORMAT_DPCM_10_8_10:
248 *decode_fmt = 0x8;
249 *plain_fmt = 0x1;
250 break;
251 case CAM_FORMAT_DPCM_12_6_12:
252 *decode_fmt = 0x9;
253 *plain_fmt = 0x1;
254 break;
255 case CAM_FORMAT_DPCM_12_8_12:
256 *decode_fmt = 0xA;
257 *plain_fmt = 0x1;
258 break;
259 case CAM_FORMAT_DPCM_14_8_14:
260 *decode_fmt = 0xB;
261 *plain_fmt = 0x1;
262 break;
263 case CAM_FORMAT_DPCM_14_10_14:
264 *decode_fmt = 0xC;
265 *plain_fmt = 0x1;
266 break;
267 default:
268 CAM_ERR(CAM_ISP, "Unsupported format %d",
269 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700270 rc = -EINVAL;
271 }
272
Harsh Shahf7136392017-08-29 12:42:52 -0700273 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
274 *decode_fmt, *plain_fmt);
275
Jing Zhouff57d862017-03-21 00:54:25 -0700276 return rc;
277}
278
279static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
280 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
281 uint32_t res_type)
282{
283 int rc = 0;
284 struct cam_ife_csid_cid_data *cid_data;
285 uint32_t i = 0, j = 0;
286
287 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
288 if (csid_hw->cid_res[i].res_state >=
289 CAM_ISP_RESOURCE_STATE_RESERVED) {
290 cid_data = (struct cam_ife_csid_cid_data *)
291 csid_hw->cid_res[i].res_priv;
292 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
293 if (cid_data->tpg_set) {
294 cid_data->cnt++;
295 *res = &csid_hw->cid_res[i];
296 break;
297 }
298 } else {
299 if (cid_data->vc == vc && cid_data->dt == dt) {
300 cid_data->cnt++;
301 *res = &csid_hw->cid_res[i];
302 break;
303 }
304 }
305 }
306 }
307
308 if (i == CAM_IFE_CSID_CID_RES_MAX) {
309 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700310 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
311 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700312 rc = -EINVAL;
313 }
314
315 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
316 if (csid_hw->cid_res[j].res_state ==
317 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
318 cid_data = (struct cam_ife_csid_cid_data *)
319 csid_hw->cid_res[j].res_priv;
320 cid_data->vc = vc;
321 cid_data->dt = dt;
322 cid_data->cnt = 1;
323 csid_hw->cid_res[j].res_state =
324 CAM_ISP_RESOURCE_STATE_RESERVED;
325 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700326 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700327 csid_hw->hw_intf->hw_idx,
328 csid_hw->cid_res[j].res_id);
329 break;
330 }
331 }
332
333 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700334 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
335 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700336 rc = -EINVAL;
337 }
338 }
339
340 return rc;
341}
342
343
344static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
345{
346 struct cam_hw_soc_info *soc_info;
347 struct cam_ife_csid_reg_offset *csid_reg;
348 int rc = 0;
349 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
350 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
351
352 soc_info = &csid_hw->hw_info->soc_info;
353 csid_reg = csid_hw->csid_info->csid_reg;
354
355 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700356 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
357 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700358 csid_hw->hw_info->hw_state);
359 return -EINVAL;
360 }
361
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700362 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700363 csid_hw->hw_intf->hw_idx);
364
365 init_completion(&csid_hw->csid_top_complete);
366
367 /* Save interrupt mask registers values*/
368 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
369 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
370
371 if (csid_reg->cmn_reg->no_pix)
372 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
373 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
374
375 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
376 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
377 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
378 }
379
380 /* Mask all interrupts */
381 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
382 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
383
384 if (csid_reg->cmn_reg->no_pix)
385 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
386 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
387
388 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
389 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
390 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
391
392 /* clear all interrupts */
393 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
394 csid_reg->cmn_reg->csid_top_irq_clear_addr);
395
396 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
397 soc_info->reg_map[0].mem_base +
398 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
399
400 if (csid_reg->cmn_reg->no_pix)
401 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
402 soc_info->reg_map[0].mem_base +
403 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
404
405 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
406 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
407 soc_info->reg_map[0].mem_base +
408 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
409
410 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
411 csid_reg->cmn_reg->csid_irq_cmd_addr);
412
413 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
414 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
415
416 /* enable the IPP and RDI format measure */
417 if (csid_reg->cmn_reg->no_pix)
418 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
419 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
420
421 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
422 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
423 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
424
425 /* perform the top CSID HW reset */
426 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
427 soc_info->reg_map[0].mem_base +
428 csid_reg->cmn_reg->csid_rst_strobes_addr);
429
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700430 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700431 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
432 msecs_to_jiffies(IFE_CSID_TIMEOUT));
433 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700434 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
435 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700436 if (rc == 0)
437 rc = -ETIMEDOUT;
438 } else {
439 rc = 0;
440 }
441
442 /*restore all interrupt masks */
443 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
444 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
445
446 if (csid_reg->cmn_reg->no_pix)
447 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
448 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
449
450 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
451 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
452 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
453
454 return rc;
455}
456
457static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
458 struct cam_csid_reset_cfg_args *reset)
459{
460 int rc = 0;
461 struct cam_hw_soc_info *soc_info;
462 struct cam_isp_resource_node *res;
463 struct cam_ife_csid_reg_offset *csid_reg;
464 uint32_t reset_strb_addr, reset_strb_val, val, id;
465 struct completion *complete;
466
467 csid_reg = csid_hw->csid_info->csid_reg;
468 soc_info = &csid_hw->hw_info->soc_info;
469 res = reset->node_res;
470
471 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700472 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
473 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700474 csid_hw->hw_info->hw_state);
475 return -EINVAL;
476 }
477
478 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700479 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
480 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700481 rc = -EINVAL;
482 goto end;
483 }
484
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700485 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700486 csid_hw->hw_intf->hw_idx, res->res_id);
487
488 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
489 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700490 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
491 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700492 res->res_id);
493 return -EINVAL;
494 }
495
496 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
497 complete = &csid_hw->csid_ipp_complete;
498
499 /* Enable path reset done interrupt */
500 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
501 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
502 val |= CSID_PATH_INFO_RST_DONE;
503 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
504 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
505
506 } else {
507 id = res->res_id;
508 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700509 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
510 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700511 res->res_id);
512 return -EINVAL;
513 }
514
515 reset_strb_addr =
516 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
517 complete =
518 &csid_hw->csid_rdin_complete[id];
519
520 /* Enable path reset done interrupt */
521 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
522 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
523 val |= CSID_PATH_INFO_RST_DONE;
524 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
525 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
526 }
527
528 init_completion(complete);
529 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
530
531 /* Enable the Test gen before reset */
532 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
533 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
534
535 /* Reset the corresponding ife csid path */
536 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
537 reset_strb_addr);
538
539 rc = wait_for_completion_timeout(complete,
540 msecs_to_jiffies(IFE_CSID_TIMEOUT));
541 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700542 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
543 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700544 res->res_id, rc);
545 if (rc == 0)
546 rc = -ETIMEDOUT;
547 }
548
549 /* Disable Test Gen after reset*/
550 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
551 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
552
553end:
554 return rc;
555
556}
557
558static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
559 struct cam_csid_hw_reserve_resource_args *cid_reserv)
560{
561 int rc = 0;
562 struct cam_ife_csid_cid_data *cid_data;
563
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700564 CAM_DBG(CAM_ISP,
565 "CSID:%d res_sel:%d Lane type:%d lane_num:%d dt:%d vc:%d",
566 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700567 cid_reserv->in_port->res_type,
568 cid_reserv->in_port->lane_type,
569 cid_reserv->in_port->lane_num,
570 cid_reserv->in_port->dt,
571 cid_reserv->in_port->vc);
572
573 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700574 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
575 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700576 cid_reserv->in_port->res_type);
577 rc = -EINVAL;
578 goto end;
579 }
580
581 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
582 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700583 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
584 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700585 cid_reserv->in_port->lane_type);
586 rc = -EINVAL;
587 goto end;
588 }
589
590 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
591 cid_reserv->in_port->lane_num > 4) &&
592 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700593 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
594 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700595 cid_reserv->in_port->lane_num);
596 rc = -EINVAL;
597 goto end;
598 }
599 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
600 cid_reserv->in_port->lane_num > 3) &&
601 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700602 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
603 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700604 cid_reserv->in_port->lane_type,
605 cid_reserv->in_port->lane_num);
606 rc = -EINVAL;
607 goto end;
608 }
609
610 /* CSID CSI2 v2.0 supports 31 vc */
611 if (cid_reserv->in_port->dt > 0x3f ||
612 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700613 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
614 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700615 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
616 rc = -EINVAL;
617 goto end;
618 }
619
620 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
621 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
622 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700623 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
624 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700625 cid_reserv->in_port->format);
626 rc = -EINVAL;
627 goto end;
628 }
629
630 if (csid_hw->csi2_reserve_cnt) {
631 /* current configure res type should match requested res type */
632 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
633 rc = -EINVAL;
634 goto end;
635 }
636
637 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
638 if (csid_hw->csi2_rx_cfg.lane_cfg !=
639 cid_reserv->in_port->lane_cfg ||
640 csid_hw->csi2_rx_cfg.lane_type !=
641 cid_reserv->in_port->lane_type ||
642 csid_hw->csi2_rx_cfg.lane_num !=
643 cid_reserv->in_port->lane_num) {
644 rc = -EINVAL;
645 goto end;
646 }
647 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700648 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700649 cid_reserv->in_port->format ||
650 csid_hw->tpg_cfg.width !=
651 cid_reserv->in_port->left_width ||
652 csid_hw->tpg_cfg.height !=
653 cid_reserv->in_port->height ||
654 csid_hw->tpg_cfg.test_pattern !=
655 cid_reserv->in_port->test_pattern) {
656 rc = -EINVAL;
657 goto end;
658 }
659 }
660 }
661
662 if (!csid_hw->csi2_reserve_cnt) {
663 csid_hw->res_type = cid_reserv->in_port->res_type;
664 /* Take the first CID resource*/
665 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
666 cid_data = (struct cam_ife_csid_cid_data *)
667 csid_hw->cid_res[0].res_priv;
668
669 csid_hw->csi2_rx_cfg.lane_cfg =
670 cid_reserv->in_port->lane_cfg;
671 csid_hw->csi2_rx_cfg.lane_type =
672 cid_reserv->in_port->lane_type;
673 csid_hw->csi2_rx_cfg.lane_num =
674 cid_reserv->in_port->lane_num;
675
676 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
677 csid_hw->csi2_rx_cfg.phy_sel = 0;
678 if (cid_reserv->in_port->format >
679 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700680 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700681 rc = -EINVAL;
682 goto end;
683 }
Harsh Shahf7136392017-08-29 12:42:52 -0700684 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700685 cid_reserv->in_port->format;
686 csid_hw->tpg_cfg.width =
687 cid_reserv->in_port->left_width;
688 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
689 csid_hw->tpg_cfg.test_pattern =
690 cid_reserv->in_port->test_pattern;
691 cid_data->tpg_set = 1;
692 } else {
693 csid_hw->csi2_rx_cfg.phy_sel =
694 (cid_reserv->in_port->res_type & 0xFF) - 1;
695 }
696
697 cid_data->vc = cid_reserv->in_port->vc;
698 cid_data->dt = cid_reserv->in_port->dt;
699 cid_data->cnt = 1;
700 cid_reserv->node_res = &csid_hw->cid_res[0];
701 csid_hw->csi2_reserve_cnt++;
702
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700703 CAM_DBG(CAM_ISP,
704 "CSID:%d CID :%d resource acquired successfully",
705 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700706 cid_reserv->node_res->res_id);
707 } else {
708 rc = cam_ife_csid_cid_get(csid_hw, &cid_reserv->node_res,
709 cid_reserv->in_port->vc, cid_reserv->in_port->dt,
710 cid_reserv->in_port->res_type);
711 /* if success then increment the reserve count */
712 if (!rc) {
713 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700714 CAM_ERR(CAM_ISP,
715 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700716 csid_hw->hw_intf->hw_idx);
717 rc = -EINVAL;
718 } else {
719 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700720 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700721 csid_hw->hw_intf->hw_idx,
722 cid_reserv->node_res->res_id);
723 }
724 }
725 }
726
727end:
728 return rc;
729}
730
731
732static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
733 struct cam_csid_hw_reserve_resource_args *reserve)
734{
735 int rc = 0;
736 struct cam_ife_csid_path_cfg *path_data;
737 struct cam_isp_resource_node *res;
738
739 /* CSID CSI2 v2.0 supports 31 vc */
740 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
741 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700742 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
743 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700744 reserve->in_port->vc, reserve->in_port->dt,
745 reserve->sync_mode);
746 rc = -EINVAL;
747 goto end;
748 }
749
750 switch (reserve->res_id) {
751 case CAM_IFE_PIX_PATH_RES_IPP:
752 if (csid_hw->ipp_res.res_state !=
753 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700754 CAM_DBG(CAM_ISP,
755 "CSID:%d IPP resource not available %d",
756 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700757 csid_hw->ipp_res.res_state);
758 rc = -EINVAL;
759 goto end;
760 }
761
762 if (cam_ife_csid_is_ipp_format_supported(
763 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700764 CAM_ERR(CAM_ISP,
765 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700766 csid_hw->hw_intf->hw_idx, reserve->res_id,
767 reserve->in_port->format);
768 rc = -EINVAL;
769 goto end;
770 }
771
772 /* assign the IPP resource */
773 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700774 CAM_DBG(CAM_ISP,
775 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700776 csid_hw->hw_intf->hw_idx, res->res_id);
777
778 break;
779 case CAM_IFE_PIX_PATH_RES_RDI_0:
780 case CAM_IFE_PIX_PATH_RES_RDI_1:
781 case CAM_IFE_PIX_PATH_RES_RDI_2:
782 case CAM_IFE_PIX_PATH_RES_RDI_3:
783 if (csid_hw->rdi_res[reserve->res_id].res_state !=
784 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700785 CAM_DBG(CAM_ISP,
786 "CSID:%d RDI:%d resource not available %d",
787 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700788 reserve->res_id,
789 csid_hw->rdi_res[reserve->res_id].res_state);
790 rc = -EINVAL;
791 goto end;
792 } else {
793 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700794 CAM_DBG(CAM_ISP,
795 "CSID:%d RDI resource:%d acquire success",
796 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700797 res->res_id);
798 }
799
800 break;
801 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700802 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700803 csid_hw->hw_intf->hw_idx, reserve->res_id);
804 rc = -EINVAL;
805 goto end;
806 }
807
808 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
809 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
810
811 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700812 path_data->in_format = reserve->in_port->format;
813 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700814 path_data->master_idx = reserve->master_idx;
815 path_data->sync_mode = reserve->sync_mode;
816 path_data->height = reserve->in_port->height;
817 path_data->start_line = reserve->in_port->line_start;
818 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
819 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
820 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
821 } else {
822 path_data->dt = reserve->in_port->dt;
823 path_data->vc = reserve->in_port->vc;
824 }
825
826 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
827 path_data->crop_enable = 1;
828 path_data->start_pixel = reserve->in_port->left_start;
829 path_data->width = reserve->in_port->left_width;
830 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
831 path_data->crop_enable = 1;
832 path_data->start_pixel = reserve->in_port->right_start;
833 path_data->width = reserve->in_port->right_width;
Harsh Shahf7136392017-08-29 12:42:52 -0700834 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700835 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700836 path_data->width = reserve->in_port->left_width;
837 path_data->start_pixel = reserve->in_port->left_start;
838 }
Jing Zhouff57d862017-03-21 00:54:25 -0700839
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530840 CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
Harsh Shahf7136392017-08-29 12:42:52 -0700841 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700842 reserve->node_res = res;
843
844end:
845 return rc;
846}
847
848static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
849{
850 int rc = 0;
851 struct cam_ife_csid_reg_offset *csid_reg;
852 struct cam_hw_soc_info *soc_info;
853 uint32_t i, status, val;
854
855 csid_reg = csid_hw->csid_info->csid_reg;
856 soc_info = &csid_hw->hw_info->soc_info;
857
858 /* overflow check before increment */
859 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700860 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
861 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700862 return -EINVAL;
863 }
864
865 /* Increment ref Count */
866 csid_hw->hw_info->open_count++;
867 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700868 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700869 return rc;
870 }
871
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700872 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700873 csid_hw->hw_intf->hw_idx);
874
875 rc = cam_ife_csid_enable_soc_resources(soc_info);
876 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700877 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700878 csid_hw->hw_intf->hw_idx);
879 goto err;
880 }
881
882
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700883 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700884 csid_hw->hw_intf->hw_idx);
885
886 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
887 /* Enable the top IRQ interrupt */
888 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
889 csid_reg->cmn_reg->csid_top_irq_mask_addr);
890
891 rc = cam_ife_csid_global_reset(csid_hw);
892 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700893 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
894 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700895 rc = -ETIMEDOUT;
896 goto disable_soc;
897 }
898
899 /*
900 * Reset the SW registers
901 * SW register reset also reset the mask irq, so poll the irq status
902 * to check the reset complete.
903 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700904 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700905 csid_hw->hw_intf->hw_idx);
906
907 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
908 soc_info->reg_map[0].mem_base +
909 csid_reg->cmn_reg->csid_rst_strobes_addr);
910
911 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
912 csid_reg->cmn_reg->csid_top_irq_status_addr,
913 status, (status & 0x1) == 0x1,
914 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
915 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700916 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700917 rc = -ETIMEDOUT;
918 goto disable_soc;
919 }
920
921 /* clear all interrupts */
922 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
923 csid_reg->cmn_reg->csid_top_irq_clear_addr);
924
925 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
926 soc_info->reg_map[0].mem_base +
927 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
928
929 if (csid_reg->cmn_reg->no_pix)
930 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
931 soc_info->reg_map[0].mem_base +
932 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
933
934 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
935 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
936 soc_info->reg_map[0].mem_base +
937 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
938
939 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
940 csid_reg->cmn_reg->csid_irq_cmd_addr);
941
942 /* Enable the top IRQ interrupt */
943 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
944 csid_reg->cmn_reg->csid_top_irq_mask_addr);
945
946 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
947 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700948 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -0700949 csid_hw->hw_intf->hw_idx, val);
950
951 return 0;
952
953disable_soc:
954 cam_ife_csid_disable_soc_resources(soc_info);
955 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
956err:
957 csid_hw->hw_info->open_count--;
958 return rc;
959}
960
961static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
962{
963 int rc = 0;
964 struct cam_hw_soc_info *soc_info;
965 struct cam_ife_csid_reg_offset *csid_reg;
966
967
968 /* Decrement ref Count */
969 if (csid_hw->hw_info->open_count)
970 csid_hw->hw_info->open_count--;
971 if (csid_hw->hw_info->open_count)
972 return rc;
973
974 soc_info = &csid_hw->hw_info->soc_info;
975 csid_reg = csid_hw->csid_info->csid_reg;
976
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700977 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700978 csid_hw->hw_intf->hw_idx);
979
980 /*disable the top IRQ interrupt */
981 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
982 csid_reg->cmn_reg->csid_top_irq_mask_addr);
983
984 rc = cam_ife_csid_disable_soc_resources(soc_info);
985 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700986 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
987 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700988
989 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
990 return rc;
991}
992
993
994static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
995 struct cam_isp_resource_node *res)
996{
997 uint32_t val = 0;
998 struct cam_hw_soc_info *soc_info;
999
1000 csid_hw->tpg_start_cnt++;
1001 if (csid_hw->tpg_start_cnt == 1) {
1002 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001003 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1004 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001005
1006 soc_info = &csid_hw->hw_info->soc_info;
1007 {
1008 uint32_t val;
1009 uint32_t i;
1010 uint32_t base = 0x600;
1011
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001012 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001013 for (i = 0; i < 16; i++) {
1014 val = cam_io_r_mb(
1015 soc_info->reg_map[0].mem_base +
1016 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001017 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001018 (base + i*4), val);
1019 }
1020
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001021 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001022 base = 0x200;
1023 for (i = 0; i < 10; i++) {
1024 val = cam_io_r_mb(
1025 soc_info->reg_map[0].mem_base +
1026 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001027 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001028 (base + i*4), val);
1029 }
1030
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001031 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001032 base = 0x100;
1033 for (i = 0; i < 5; i++) {
1034 val = cam_io_r_mb(
1035 soc_info->reg_map[0].mem_base +
1036 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001037 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001038 (base + i*4), val);
1039 }
1040 }
1041
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001042 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001043 val = (4 << 20);
1044 val |= (0x80 << 8);
1045 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1046 val |= 7;
1047 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1048 csid_hw->csid_info->csid_reg->tpg_reg->
1049 csid_tpg_ctrl_addr);
1050
1051 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001052 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001053 }
1054
1055 return 0;
1056}
1057
1058static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1059 struct cam_isp_resource_node *res)
1060{
1061 struct cam_hw_soc_info *soc_info;
1062
1063 if (csid_hw->tpg_start_cnt)
1064 csid_hw->tpg_start_cnt--;
1065
1066 if (csid_hw->tpg_start_cnt)
1067 return 0;
1068
1069 soc_info = &csid_hw->hw_info->soc_info;
1070
1071 /* disable the TPG */
1072 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001073 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1074 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001075
1076 /*stop the TPG */
1077 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1078 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1079 }
1080
1081 return 0;
1082}
1083
1084
1085static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1086 struct cam_isp_resource_node *res)
1087{
1088 struct cam_ife_csid_reg_offset *csid_reg;
1089 struct cam_hw_soc_info *soc_info;
1090 uint32_t val = 0;
1091
1092 csid_reg = csid_hw->csid_info->csid_reg;
1093 soc_info = &csid_hw->hw_info->soc_info;
1094
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001095 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1096 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001097
1098 /* configure one DT, infinite frames */
1099 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1100 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1101 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1102
1103 /* vertical blanking count = 0x740, horzontal blanking count = 0x740*/
1104 val = (0x740 << 12) | 0x740;
1105 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1106 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1107
1108 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1109 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1110
1111 val = csid_hw->tpg_cfg.width << 16 |
1112 csid_hw->tpg_cfg.height;
1113 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1114 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1115
1116 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1117 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1118
1119 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001120 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001121 * it is one larger than the register spec format.
1122 */
Harsh Shahf7136392017-08-29 12:42:52 -07001123 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001124 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1125 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1126
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001127 /* static frame with split color bar */
1128 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001129 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1130 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1131 /* config pix pattern */
1132 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1133 soc_info->reg_map[0].mem_base +
1134 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1135
1136 return 0;
1137}
1138
1139static int cam_ife_csid_enable_csi2(
1140 struct cam_ife_csid_hw *csid_hw,
1141 struct cam_isp_resource_node *res)
1142{
1143 int rc = 0;
1144 struct cam_ife_csid_reg_offset *csid_reg;
1145 struct cam_hw_soc_info *soc_info;
1146 struct cam_ife_csid_cid_data *cid_data;
1147 uint32_t val = 0;
1148
1149 csid_reg = csid_hw->csid_info->csid_reg;
1150 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001151 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1152 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001153
1154 /* overflow check before increment */
1155 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001156 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1157 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001158 return -EINVAL;
1159 }
1160
1161 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1162
1163 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1164 csid_hw->csi2_cfg_cnt++;
1165 if (csid_hw->csi2_cfg_cnt > 1)
1166 return rc;
1167
1168 /* rx cfg0 */
1169 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1170 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1171 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001172 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001173 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1174 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1175
1176 /* rx cfg1*/
1177 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1178 /* if VC value is more than 3 than set full width of VC */
1179 if (cid_data->vc > 3)
1180 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1181
1182 /* enable packet ecc correction */
1183 val |= 1;
1184 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1185 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1186
1187 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1188 /* Config the TPG */
1189 rc = cam_ife_csid_config_tpg(csid_hw, res);
1190 if (rc) {
1191 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1192 return rc;
1193 }
1194 }
1195
1196 /*Enable the CSI2 rx inerrupts */
1197 val = CSID_CSI2_RX_INFO_RST_DONE |
1198 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1199 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1200 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1201 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1202 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1203 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1204 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
1205 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301206
1207 /* Enable the interrupt based on csid debug info set */
1208 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ)
1209 val |= CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED |
1210 CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED |
1211 CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED |
1212 CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED;
1213
1214 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ)
1215 val |= CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED |
1216 CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED |
1217 CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED |
1218 CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED;
1219
1220 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1221 val |= CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED;
1222
1223 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1224 val |= CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED;
1225 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1226 val |= CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED;
1227
Jing Zhouff57d862017-03-21 00:54:25 -07001228 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1229 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1230
1231 return 0;
1232}
1233
1234static int cam_ife_csid_disable_csi2(
1235 struct cam_ife_csid_hw *csid_hw,
1236 struct cam_isp_resource_node *res)
1237{
1238 struct cam_ife_csid_reg_offset *csid_reg;
1239 struct cam_hw_soc_info *soc_info;
1240
1241 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001242 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1243 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001244 return -EINVAL;
1245 }
1246
1247 csid_reg = csid_hw->csid_info->csid_reg;
1248 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001249 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1250 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001251
1252 if (csid_hw->csi2_cfg_cnt)
1253 csid_hw->csi2_cfg_cnt--;
1254
1255 if (csid_hw->csi2_cfg_cnt)
1256 return 0;
1257
1258 /*Disable the CSI2 rx inerrupts */
1259 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1260 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1261
1262 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1263
1264 return 0;
1265}
1266
1267static int cam_ife_csid_init_config_ipp_path(
1268 struct cam_ife_csid_hw *csid_hw,
1269 struct cam_isp_resource_node *res)
1270{
1271 int rc = 0;
1272 struct cam_ife_csid_path_cfg *path_data;
1273 struct cam_ife_csid_reg_offset *csid_reg;
1274 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001275 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001276
1277 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1278 csid_reg = csid_hw->csid_info->csid_reg;
1279 soc_info = &csid_hw->hw_info->soc_info;
1280
1281 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001282 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1283 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001284 res->res_id);
1285 return -EINVAL;
1286 }
1287
Harsh Shahf7136392017-08-29 12:42:52 -07001288 CAM_DBG(CAM_ISP, "Config IPP Path");
1289 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1290 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001291 if (rc)
1292 return rc;
1293
Jing Zhoubb536a82017-05-18 15:20:38 -07001294 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001295 * configure the IPP and enable the time stamp capture.
1296 * enable the HW measrurement blocks
1297 */
1298 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1299 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1300 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001301 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Jing Zhouff57d862017-03-21 00:54:25 -07001302 (path_data->crop_enable & 1 <<
1303 csid_reg->cmn_reg->crop_h_en_shift_val) |
1304 (path_data->crop_enable & 1 <<
1305 csid_reg->cmn_reg->crop_v_en_shift_val) |
1306 (1 << 1) | 1;
1307 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1308 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1309 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1310
Jing Zhoudedc4762017-06-19 17:45:36 +05301311 /* select the post irq sub sample strobe for time stamp capture */
1312 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1313 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1314
Jing Zhouff57d862017-03-21 00:54:25 -07001315 if (path_data->crop_enable) {
1316 val = ((path_data->width +
1317 path_data->start_pixel) & 0xFFFF <<
1318 csid_reg->cmn_reg->crop_shift) |
1319 (path_data->start_pixel & 0xFFFF);
1320
1321 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1322 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
1323
1324 val = ((path_data->height +
1325 path_data->start_line) & 0xFFFF <<
1326 csid_reg->cmn_reg->crop_shift) |
1327 (path_data->start_line & 0xFFFF);
1328
1329 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1330 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
1331 }
1332
1333 /* set frame drop pattern to 0 and period to 1 */
1334 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1335 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1336 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1337 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1338 /* set irq sub sample pattern to 0 and period to 1 */
1339 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1340 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1341 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1342 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1343 /* set pixel drop pattern to 0 and period to 1 */
1344 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1345 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1346 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1347 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1348 /* set line drop pattern to 0 and period to 1 */
1349 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1350 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1351 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1352 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1353
1354 /*Set master or slave IPP */
1355 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1356 /*Set halt mode as master */
1357 val = CSID_HALT_MODE_MASTER << 2;
1358 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1359 /*Set halt mode as slave and set master idx */
1360 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1361 else
1362 /* Default is internal halt mode */
1363 val = 0;
1364
1365 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1366 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1367
1368 /* Enable the IPP path */
1369 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1370 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1371 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1372 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1373 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1374
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301375 /* configure the rx packet capture based on csid debug set */
1376 val = 0;
1377 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1378 val = ((1 <<
1379 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1380 (path_data->vc <<
1381 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1382
1383 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1384 val |= ((1 <<
1385 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1386 (path_data->dt <<
1387 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1388 (path_data->vc <<
1389 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1390
1391 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1392 val |= ((1 <<
1393 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1394 (path_data->dt <<
1395 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1396 (path_data->vc <<
1397 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1398
1399 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1400 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1401 CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val);
1402
Jing Zhouff57d862017-03-21 00:54:25 -07001403 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1404
1405 return rc;
1406}
1407
1408static int cam_ife_csid_deinit_ipp_path(
1409 struct cam_ife_csid_hw *csid_hw,
1410 struct cam_isp_resource_node *res)
1411{
1412 int rc = 0;
1413 struct cam_ife_csid_reg_offset *csid_reg;
1414 struct cam_hw_soc_info *soc_info;
1415 uint32_t val = 0;
1416
1417 csid_reg = csid_hw->csid_info->csid_reg;
1418 soc_info = &csid_hw->hw_info->soc_info;
1419
1420 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001421 CAM_ERR(CAM_ISP,
1422 "CSID:%d Res type %d res_id:%d in wrong state %d",
1423 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001424 res->res_type, res->res_id, res->res_state);
1425 rc = -EINVAL;
1426 }
1427
1428 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001429 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1430 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001431 res->res_id);
1432 rc = -EINVAL;
1433 }
1434
1435 /* Disable the IPP path */
1436 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1437 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1438 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1439 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1440 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1441
1442 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1443 return rc;
1444}
1445
1446static int cam_ife_csid_enable_ipp_path(
1447 struct cam_ife_csid_hw *csid_hw,
1448 struct cam_isp_resource_node *res)
1449{
1450 struct cam_ife_csid_reg_offset *csid_reg;
1451 struct cam_hw_soc_info *soc_info;
1452 struct cam_ife_csid_path_cfg *path_data;
1453 uint32_t val = 0;
1454
1455 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1456 csid_reg = csid_hw->csid_info->csid_reg;
1457 soc_info = &csid_hw->hw_info->soc_info;
1458
1459 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001460 CAM_ERR(CAM_ISP,
1461 "CSID:%d res type:%d res_id:%d Invalid state%d",
1462 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001463 res->res_type, res->res_id, res->res_state);
1464 return -EINVAL;
1465 }
1466
1467 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001468 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1469 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001470 res->res_id);
1471 return -EINVAL;
1472 }
1473
Harsh Shahf7136392017-08-29 12:42:52 -07001474 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001475
Harsh Shahf7136392017-08-29 12:42:52 -07001476 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001477 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1478 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1479 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1480 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1481 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1482 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1483 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1484 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1485 soc_info->reg_map[0].mem_base +
1486 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1487 }
1488 /* for slave mode, not need to resume for slave device */
1489
1490 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301491 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301492
1493 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1494 val |= CSID_PATH_INFO_INPUT_SOF;
1495 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1496 val |= CSID_PATH_INFO_INPUT_EOF;
1497
Jing Zhouff57d862017-03-21 00:54:25 -07001498 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1499 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1500
1501 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1502
1503 return 0;
1504}
1505
1506static int cam_ife_csid_disable_ipp_path(
1507 struct cam_ife_csid_hw *csid_hw,
1508 struct cam_isp_resource_node *res,
1509 enum cam_ife_csid_halt_cmd stop_cmd)
1510{
1511 int rc = 0;
1512 struct cam_ife_csid_reg_offset *csid_reg;
1513 struct cam_hw_soc_info *soc_info;
1514 struct cam_ife_csid_path_cfg *path_data;
1515 uint32_t val = 0;
1516
1517 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1518 csid_reg = csid_hw->csid_info->csid_reg;
1519 soc_info = &csid_hw->hw_info->soc_info;
1520
1521 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001522 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1523 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001524 return -EINVAL;
1525 }
1526
1527 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1528 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001529 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1530 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001531 res->res_id, res->res_state);
1532 return rc;
1533 }
1534
1535 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001536 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1537 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001538 res->res_state);
1539 return -EINVAL;
1540 }
1541
1542 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001543 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1544 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001545 return -EINVAL;
1546 }
1547
1548 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1549 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001550 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1551 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001552 return -EINVAL;
1553 }
1554
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001555 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001556 csid_hw->hw_intf->hw_idx, res->res_id);
1557
1558 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1559 /* configure Halt */
1560 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1561 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1562 val &= ~0x3;
1563 val |= stop_cmd;
1564 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1565 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1566 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1567 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1568 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1569
1570 /* For slave mode, halt command should take it from master */
1571
1572 /* Enable the EOF interrupt for resume at boundary case */
1573 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1574 init_completion(&csid_hw->csid_ipp_complete);
1575 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1576 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1577 val |= CSID_PATH_INFO_INPUT_EOF;
1578 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1579 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1580 } else {
1581 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001582 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001583 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1584 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1585 }
1586
1587 return rc;
1588}
1589
1590
1591static int cam_ife_csid_init_config_rdi_path(
1592 struct cam_ife_csid_hw *csid_hw,
1593 struct cam_isp_resource_node *res)
1594{
1595 int rc = 0;
1596 struct cam_ife_csid_path_cfg *path_data;
1597 struct cam_ife_csid_reg_offset *csid_reg;
1598 struct cam_hw_soc_info *soc_info;
1599 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1600
1601 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1602 csid_reg = csid_hw->csid_info->csid_reg;
1603 soc_info = &csid_hw->hw_info->soc_info;
1604
1605 id = res->res_id;
1606 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001607 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1608 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001609 return -EINVAL;
1610 }
1611
Harsh Shahf7136392017-08-29 12:42:52 -07001612 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1613 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001614 if (rc)
1615 return rc;
1616
Jing Zhoubb536a82017-05-18 15:20:38 -07001617 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001618 * RDI path config and enable the time stamp capture
1619 * Enable the measurement blocks
1620 */
1621 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1622 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1623 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1624 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1625 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
1626 (path_data->crop_enable & 1 <<
1627 csid_reg->cmn_reg->crop_h_en_shift_val) |
1628 (path_data->crop_enable & 1 <<
1629 csid_reg->cmn_reg->crop_v_en_shift_val) |
1630 (1 << 2) | 3;
1631
1632 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1633 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1634
Jing Zhoudedc4762017-06-19 17:45:36 +05301635 /* select the post irq sub sample strobe for time stamp capture */
1636 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1637 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1638
Jing Zhouff57d862017-03-21 00:54:25 -07001639 if (path_data->crop_enable) {
1640 val = ((path_data->width +
1641 path_data->start_pixel) & 0xFFFF <<
1642 csid_reg->cmn_reg->crop_shift) |
1643 (path_data->start_pixel & 0xFFFF);
1644
1645 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1646 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
1647
1648 val = ((path_data->height +
1649 path_data->start_line) & 0xFFFF <<
1650 csid_reg->cmn_reg->crop_shift) |
1651 (path_data->start_line & 0xFFFF);
1652
1653 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1654 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
1655 }
1656 /* set frame drop pattern to 0 and period to 1 */
1657 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1658 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1659 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1660 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1661 /* set IRQ sum sabmple */
1662 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1663 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1664 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1665 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1666
1667 /* set pixel drop pattern to 0 and period to 1 */
1668 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1669 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1670 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1671 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1672 /* set line drop pattern to 0 and period to 1 */
1673 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1674 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1675 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1676 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1677
1678 /* Configure the halt mode */
1679 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1680 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1681
1682 /* Enable the RPP path */
1683 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1684 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1685 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001686
Jing Zhouff57d862017-03-21 00:54:25 -07001687 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1688 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1689
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301690 /* configure the rx packet capture based on csid debug set */
1691 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1692 val = ((1 <<
1693 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1694 (path_data->vc <<
1695 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1696
1697 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1698 val |= ((1 <<
1699 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1700 (path_data->dt <<
1701 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1702 (path_data->vc <<
1703 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1704
1705 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1706 val |= ((1 <<
1707 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1708 (path_data->dt <<
1709 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1710 (path_data->vc <<
1711 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1712 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1713 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1714
Jing Zhouff57d862017-03-21 00:54:25 -07001715 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1716
1717 return rc;
1718}
1719
1720static int cam_ife_csid_deinit_rdi_path(
1721 struct cam_ife_csid_hw *csid_hw,
1722 struct cam_isp_resource_node *res)
1723{
1724 int rc = 0;
1725 struct cam_ife_csid_reg_offset *csid_reg;
1726 struct cam_hw_soc_info *soc_info;
1727 uint32_t val = 0, id;
1728
1729 csid_reg = csid_hw->csid_info->csid_reg;
1730 soc_info = &csid_hw->hw_info->soc_info;
1731 id = res->res_id;
1732
1733 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1734 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1735 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001736 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1737 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001738 res->res_state);
1739 return -EINVAL;
1740 }
1741
1742 /* Disable the RDI path */
1743 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1744 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1745 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1746 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1747 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1748
1749 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1750 return rc;
1751}
1752
1753static int cam_ife_csid_enable_rdi_path(
1754 struct cam_ife_csid_hw *csid_hw,
1755 struct cam_isp_resource_node *res)
1756{
1757 struct cam_ife_csid_reg_offset *csid_reg;
1758 struct cam_hw_soc_info *soc_info;
1759 uint32_t id, val;
1760
1761 csid_reg = csid_hw->csid_info->csid_reg;
1762 soc_info = &csid_hw->hw_info->soc_info;
1763 id = res->res_id;
1764
1765 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1766 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1767 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001768 CAM_ERR(CAM_ISP,
1769 "CSID:%d invalid res type:%d res_id:%d state%d",
1770 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001771 res->res_type, res->res_id, res->res_state);
1772 return -EINVAL;
1773 }
1774
1775 /*resume at frame boundary */
1776 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1777 soc_info->reg_map[0].mem_base +
1778 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1779
1780 /* Enable the required RDI interrupts */
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301781 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
1782
1783 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1784 val |= CSID_PATH_INFO_INPUT_SOF;
1785 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1786 val |= CSID_PATH_INFO_INPUT_EOF;
1787
Jing Zhouff57d862017-03-21 00:54:25 -07001788 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1789 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1790
1791 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1792
1793 return 0;
1794}
1795
1796
1797static int cam_ife_csid_disable_rdi_path(
1798 struct cam_ife_csid_hw *csid_hw,
1799 struct cam_isp_resource_node *res,
1800 enum cam_ife_csid_halt_cmd stop_cmd)
1801{
1802 int rc = 0;
1803 struct cam_ife_csid_reg_offset *csid_reg;
1804 struct cam_hw_soc_info *soc_info;
1805 uint32_t val = 0, id;
1806
1807 csid_reg = csid_hw->csid_info->csid_reg;
1808 soc_info = &csid_hw->hw_info->soc_info;
1809 id = res->res_id;
1810
1811 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1812 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001813 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1814 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001815 return -EINVAL;
1816 }
1817
1818 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1819 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001820 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1821 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001822 res->res_id, res->res_state);
1823 return rc;
1824 }
1825
1826 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001827 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1828 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001829 res->res_state);
1830 return -EINVAL;
1831 }
1832
1833 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1834 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001835 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1836 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001837 return -EINVAL;
1838 }
1839
1840
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001841 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001842 csid_hw->hw_intf->hw_idx, res->res_id);
1843
1844 init_completion(&csid_hw->csid_rdin_complete[id]);
1845
1846 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1847 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1848 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1849 val |= CSID_PATH_INFO_INPUT_EOF;
1850 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1851 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1852 } else {
1853 val &= ~(CSID_PATH_INFO_RST_DONE |
1854 CSID_PATH_ERROR_FIFO_OVERFLOW);
1855 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1856 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1857 }
1858
1859 /*Halt the RDI path */
1860 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1861 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1862
1863 return rc;
1864}
1865
1866static int cam_ife_csid_get_time_stamp(
1867 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1868{
1869 struct cam_csid_get_time_stamp_args *time_stamp;
1870 struct cam_isp_resource_node *res;
1871 struct cam_ife_csid_reg_offset *csid_reg;
1872 struct cam_hw_soc_info *soc_info;
1873 uint32_t time_32, id;
1874
1875 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1876 res = time_stamp->node_res;
1877 csid_reg = csid_hw->csid_info->csid_reg;
1878 soc_info = &csid_hw->hw_info->soc_info;
1879
1880 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1881 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001882 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1883 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001884 res->res_id);
1885 return -EINVAL;
1886 }
1887
1888 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001889 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1890 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001891 csid_hw->hw_info->hw_state);
1892 return -EINVAL;
1893 }
1894
1895 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1896 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1897 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1898 time_stamp->time_stamp_val = time_32;
1899 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1900 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1901 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1902 time_stamp->time_stamp_val |= time_32;
1903 } else {
1904 id = res->res_id;
1905 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1906 csid_reg->rdi_reg[id]->
1907 csid_rdi_timestamp_curr1_sof_addr);
1908 time_stamp->time_stamp_val = time_32;
1909 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1910
1911 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1912 csid_reg->rdi_reg[id]->
1913 csid_rdi_timestamp_curr0_sof_addr);
1914 time_stamp->time_stamp_val |= time_32;
1915 }
1916
1917 return 0;
1918}
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301919
1920static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw,
1921 void *cmd_args)
1922{
1923 uint32_t *csid_debug;
1924
1925 csid_debug = (uint32_t *) cmd_args;
1926 csid_hw->csid_debug = *csid_debug;
1927 CAM_DBG(CAM_ISP, "CSID:%d set csid debug value:%d",
1928 csid_hw->hw_intf->hw_idx, csid_hw->csid_debug);
1929
1930 return 0;
1931}
1932
Jing Zhouff57d862017-03-21 00:54:25 -07001933static int cam_ife_csid_res_wait_for_halt(
1934 struct cam_ife_csid_hw *csid_hw,
1935 struct cam_isp_resource_node *res)
1936{
1937 int rc = 0;
1938 struct cam_ife_csid_reg_offset *csid_reg;
1939 struct cam_hw_soc_info *soc_info;
1940
1941 struct completion *complete;
1942 uint32_t val = 0, id;
1943
1944 csid_reg = csid_hw->csid_info->csid_reg;
1945 soc_info = &csid_hw->hw_info->soc_info;
1946
1947 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001948 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1949 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001950 return -EINVAL;
1951 }
1952
1953 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1954 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001955 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1956 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001957 res->res_id, res->res_state);
1958 return rc;
1959 }
1960
1961 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001962 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1963 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001964 res->res_state);
1965 return -EINVAL;
1966 }
1967
1968 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
1969 complete = &csid_hw->csid_ipp_complete;
1970 else
1971 complete = &csid_hw->csid_rdin_complete[res->res_id];
1972
1973 rc = wait_for_completion_timeout(complete,
1974 msecs_to_jiffies(IFE_CSID_TIMEOUT));
1975 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001976 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
1977 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001978 res->res_id, rc);
1979 if (rc == 0)
1980 /* continue even have timeout */
1981 rc = -ETIMEDOUT;
1982 }
1983
1984 /* Disable the interrupt */
1985 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1986 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1987 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1988 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1989 CSID_PATH_ERROR_FIFO_OVERFLOW);
1990 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1991 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1992 } else {
1993 id = res->res_id;
1994 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1995 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1996 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1997 CSID_PATH_ERROR_FIFO_OVERFLOW);
1998 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1999 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2000 }
2001 /* set state to init HW */
2002 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
2003 return rc;
2004}
2005
2006static int cam_ife_csid_get_hw_caps(void *hw_priv,
2007 void *get_hw_cap_args, uint32_t arg_size)
2008{
2009 int rc = 0;
2010 struct cam_ife_csid_hw_caps *hw_caps;
2011 struct cam_ife_csid_hw *csid_hw;
2012 struct cam_hw_info *csid_hw_info;
2013 struct cam_ife_csid_reg_offset *csid_reg;
2014
2015 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002016 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002017 return -EINVAL;
2018 }
2019
2020 csid_hw_info = (struct cam_hw_info *)hw_priv;
2021 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2022 csid_reg = csid_hw->csid_info->csid_reg;
2023 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
2024
2025 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
2026 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
2027 hw_caps->major_version = csid_reg->cmn_reg->major_version;
2028 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
2029 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
2030
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002031 CAM_DBG(CAM_ISP,
2032 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
2033 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07002034 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
2035 hw_caps->version_incr);
2036
2037 return rc;
2038}
2039
2040static int cam_ife_csid_reset(void *hw_priv,
2041 void *reset_args, uint32_t arg_size)
2042{
2043 struct cam_ife_csid_hw *csid_hw;
2044 struct cam_hw_info *csid_hw_info;
2045 struct cam_csid_reset_cfg_args *reset;
2046 int rc = 0;
2047
2048 if (!hw_priv || !reset_args || (arg_size !=
2049 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002050 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002051 return -EINVAL;
2052 }
2053
2054 csid_hw_info = (struct cam_hw_info *)hw_priv;
2055 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2056 reset = (struct cam_csid_reset_cfg_args *)reset_args;
2057
2058 switch (reset->reset_type) {
2059 case CAM_IFE_CSID_RESET_GLOBAL:
2060 rc = cam_ife_csid_global_reset(csid_hw);
2061 break;
2062 case CAM_IFE_CSID_RESET_PATH:
2063 rc = cam_ife_csid_path_reset(csid_hw, reset);
2064 break;
2065 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002066 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
2067 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002068 rc = -EINVAL;
2069 break;
2070 }
2071
2072 return rc;
2073}
2074
2075static int cam_ife_csid_reserve(void *hw_priv,
2076 void *reserve_args, uint32_t arg_size)
2077{
2078 int rc = 0;
2079 struct cam_ife_csid_hw *csid_hw;
2080 struct cam_hw_info *csid_hw_info;
2081 struct cam_csid_hw_reserve_resource_args *reserv;
2082
2083 if (!hw_priv || !reserve_args || (arg_size !=
2084 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002085 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002086 return -EINVAL;
2087 }
2088
2089 csid_hw_info = (struct cam_hw_info *)hw_priv;
2090 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2091 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2092
2093 mutex_lock(&csid_hw->hw_info->hw_mutex);
2094 switch (reserv->res_type) {
2095 case CAM_ISP_RESOURCE_CID:
2096 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2097 break;
2098 case CAM_ISP_RESOURCE_PIX_PATH:
2099 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2100 break;
2101 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002102 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2103 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002104 rc = -EINVAL;
2105 break;
2106 }
2107 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2108 return rc;
2109}
2110
2111static int cam_ife_csid_release(void *hw_priv,
2112 void *release_args, uint32_t arg_size)
2113{
2114 int rc = 0;
2115 struct cam_ife_csid_hw *csid_hw;
2116 struct cam_hw_info *csid_hw_info;
2117 struct cam_isp_resource_node *res;
2118 struct cam_ife_csid_cid_data *cid_data;
2119
2120 if (!hw_priv || !release_args ||
2121 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002122 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002123 return -EINVAL;
2124 }
2125
2126 csid_hw_info = (struct cam_hw_info *)hw_priv;
2127 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2128 res = (struct cam_isp_resource_node *)release_args;
2129
2130 mutex_lock(&csid_hw->hw_info->hw_mutex);
2131 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2132 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2133 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2134 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002135 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2136 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002137 res->res_id);
2138 rc = -EINVAL;
2139 goto end;
2140 }
2141
2142 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002143 CAM_DBG(CAM_ISP,
2144 "CSID:%d res type:%d Res %d in released state",
2145 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002146 res->res_type, res->res_id);
2147 goto end;
2148 }
2149
2150 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2151 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002152 CAM_DBG(CAM_ISP,
2153 "CSID:%d res type:%d Res id:%d invalid state:%d",
2154 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002155 res->res_type, res->res_id, res->res_state);
2156 rc = -EINVAL;
2157 goto end;
2158 }
2159
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002160 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2161 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002162
2163 switch (res->res_type) {
2164 case CAM_ISP_RESOURCE_CID:
2165 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2166 if (cid_data->cnt)
2167 cid_data->cnt--;
2168
2169 if (!cid_data->cnt)
2170 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2171
2172 if (csid_hw->csi2_reserve_cnt)
2173 csid_hw->csi2_reserve_cnt--;
2174
2175 if (!csid_hw->csi2_reserve_cnt)
2176 memset(&csid_hw->csi2_rx_cfg, 0,
2177 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2178
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002179 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2180 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002181 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2182
2183 break;
2184 case CAM_ISP_RESOURCE_PIX_PATH:
2185 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2186 break;
2187 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002188 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2189 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002190 res->res_id);
2191 rc = -EINVAL;
2192 break;
2193 }
2194
2195end:
2196 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2197 return rc;
2198}
2199
2200static int cam_ife_csid_init_hw(void *hw_priv,
2201 void *init_args, uint32_t arg_size)
2202{
2203 int rc = 0;
2204 struct cam_ife_csid_hw *csid_hw;
2205 struct cam_hw_info *csid_hw_info;
2206 struct cam_isp_resource_node *res;
2207 struct cam_ife_csid_reg_offset *csid_reg;
2208
2209 if (!hw_priv || !init_args ||
2210 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002211 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002212 return -EINVAL;
2213 }
2214
2215 csid_hw_info = (struct cam_hw_info *)hw_priv;
2216 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2217 res = (struct cam_isp_resource_node *)init_args;
2218 csid_reg = csid_hw->csid_info->csid_reg;
2219
2220 mutex_lock(&csid_hw->hw_info->hw_mutex);
2221 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2222 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2223 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2224 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002225 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2226 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002227 res->res_id);
2228 rc = -EINVAL;
2229 goto end;
2230 }
2231
2232
2233 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2234 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002235 CAM_ERR(CAM_ISP,
2236 "CSID:%d res type:%d res_id:%dInvalid state %d",
2237 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002238 res->res_type, res->res_id, res->res_state);
2239 rc = -EINVAL;
2240 goto end;
2241 }
2242
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002243 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002244 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2245
2246
2247 /* Initialize the csid hardware */
2248 rc = cam_ife_csid_enable_hw(csid_hw);
2249 if (rc)
2250 goto end;
2251
2252 switch (res->res_type) {
2253 case CAM_ISP_RESOURCE_CID:
2254 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2255 break;
2256 case CAM_ISP_RESOURCE_PIX_PATH:
2257 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2258 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2259 else
2260 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2261
2262 break;
2263 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002264 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2265 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002266 res->res_type);
2267 break;
2268 }
2269
2270 if (rc)
2271 cam_ife_csid_disable_hw(csid_hw);
2272end:
2273 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2274 return rc;
2275}
2276
2277static int cam_ife_csid_deinit_hw(void *hw_priv,
2278 void *deinit_args, uint32_t arg_size)
2279{
2280 int rc = 0;
2281 struct cam_ife_csid_hw *csid_hw;
2282 struct cam_hw_info *csid_hw_info;
2283 struct cam_isp_resource_node *res;
2284
2285 if (!hw_priv || !deinit_args ||
2286 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002287 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002288 return -EINVAL;
2289 }
2290
2291 res = (struct cam_isp_resource_node *)deinit_args;
2292 csid_hw_info = (struct cam_hw_info *)hw_priv;
2293 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2294
2295 mutex_lock(&csid_hw->hw_info->hw_mutex);
2296 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002297 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2298 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002299 res->res_id);
2300 goto end;
2301 }
2302
2303 switch (res->res_type) {
2304 case CAM_ISP_RESOURCE_CID:
2305 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2306 break;
2307 case CAM_ISP_RESOURCE_PIX_PATH:
2308 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2309 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2310 else
2311 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2312
2313 break;
2314 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002315 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2316 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002317 res->res_type);
2318 goto end;
2319 }
2320
2321 /* Disable CSID HW */
2322 cam_ife_csid_disable_hw(csid_hw);
2323
2324end:
2325 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2326 return rc;
2327}
2328
2329static int cam_ife_csid_start(void *hw_priv, void *start_args,
2330 uint32_t arg_size)
2331{
2332 int rc = 0;
2333 struct cam_ife_csid_hw *csid_hw;
2334 struct cam_hw_info *csid_hw_info;
2335 struct cam_isp_resource_node *res;
2336 struct cam_ife_csid_reg_offset *csid_reg;
2337
2338 if (!hw_priv || !start_args ||
2339 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002340 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002341 return -EINVAL;
2342 }
2343
2344 csid_hw_info = (struct cam_hw_info *)hw_priv;
2345 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2346 res = (struct cam_isp_resource_node *)start_args;
2347 csid_reg = csid_hw->csid_info->csid_reg;
2348
Jing Zhouff57d862017-03-21 00:54:25 -07002349 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2350 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2351 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2352 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002353 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2354 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002355 res->res_id);
2356 rc = -EINVAL;
2357 goto end;
2358 }
2359
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002360 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002361 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2362
2363 switch (res->res_type) {
2364 case CAM_ISP_RESOURCE_CID:
2365 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2366 rc = cam_ife_csid_tpg_start(csid_hw, res);
2367 break;
2368 case CAM_ISP_RESOURCE_PIX_PATH:
2369 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2370 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2371 else
2372 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2373 break;
2374 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002375 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2376 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002377 res->res_type);
2378 break;
2379 }
2380end:
Jing Zhouff57d862017-03-21 00:54:25 -07002381 return rc;
2382}
2383
2384static int cam_ife_csid_stop(void *hw_priv,
2385 void *stop_args, uint32_t arg_size)
2386{
2387 int rc = 0;
2388 struct cam_ife_csid_hw *csid_hw;
2389 struct cam_hw_info *csid_hw_info;
2390 struct cam_isp_resource_node *res;
2391 struct cam_csid_hw_stop_args *csid_stop;
2392 uint32_t i;
2393
2394 if (!hw_priv || !stop_args ||
2395 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002396 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002397 return -EINVAL;
2398 }
2399 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2400 csid_hw_info = (struct cam_hw_info *)hw_priv;
2401 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2402
Jing Zhouff57d862017-03-21 00:54:25 -07002403 /* Stop the resource first */
2404 for (i = 0; i < csid_stop->num_res; i++) {
2405 res = csid_stop->node_res[i];
2406 switch (res->res_type) {
2407 case CAM_ISP_RESOURCE_CID:
2408 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2409 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2410 break;
2411 case CAM_ISP_RESOURCE_PIX_PATH:
2412 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2413 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2414 res, csid_stop->stop_cmd);
2415 else
2416 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2417 res, csid_stop->stop_cmd);
2418
2419 break;
2420 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002421 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2422 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002423 res->res_type);
2424 break;
2425 }
2426 }
2427
2428 /*wait for the path to halt */
2429 for (i = 0; i < csid_stop->num_res; i++) {
2430 res = csid_stop->node_res[i];
2431 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2432 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2433 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302434 else
2435 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002436 }
2437
Jing Zhouff57d862017-03-21 00:54:25 -07002438 return rc;
2439
2440}
2441
2442static int cam_ife_csid_read(void *hw_priv,
2443 void *read_args, uint32_t arg_size)
2444{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002445 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002446
2447 return -EINVAL;
2448}
2449
2450static int cam_ife_csid_write(void *hw_priv,
2451 void *write_args, uint32_t arg_size)
2452{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002453 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002454 return -EINVAL;
2455}
2456
2457static int cam_ife_csid_process_cmd(void *hw_priv,
2458 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2459{
2460 int rc = 0;
2461 struct cam_ife_csid_hw *csid_hw;
2462 struct cam_hw_info *csid_hw_info;
2463
2464 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002465 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002466 return -EINVAL;
2467 }
2468
2469 csid_hw_info = (struct cam_hw_info *)hw_priv;
2470 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2471
Jing Zhouff57d862017-03-21 00:54:25 -07002472 switch (cmd_type) {
2473 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2474 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2475 break;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302476 case CAM_IFE_CSID_SET_CSID_DEBUG:
2477 rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args);
2478 break;
Jing Zhouff57d862017-03-21 00:54:25 -07002479 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002480 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2481 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002482 rc = -EINVAL;
2483 break;
2484 }
Jing Zhouff57d862017-03-21 00:54:25 -07002485
2486 return rc;
2487
2488}
2489
2490irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2491{
2492 struct cam_ife_csid_hw *csid_hw;
2493 struct cam_hw_soc_info *soc_info;
2494 struct cam_ife_csid_reg_offset *csid_reg;
2495 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0,
2496 irq_status_rdi[4];
Harsh Shahf7136392017-08-29 12:42:52 -07002497 uint32_t val;
Jing Zhouff57d862017-03-21 00:54:25 -07002498
2499 csid_hw = (struct cam_ife_csid_hw *)data;
2500
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002501 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002502
2503 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002504 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002505 return IRQ_HANDLED;
2506 }
2507
2508 csid_reg = csid_hw->csid_info->csid_reg;
2509 soc_info = &csid_hw->hw_info->soc_info;
2510
2511 /* read */
2512 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2513 csid_reg->cmn_reg->csid_top_irq_status_addr);
2514
2515 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2516 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2517
2518 if (csid_reg->cmn_reg->no_pix)
2519 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2520 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2521
2522
2523 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2524 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2525 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2526
2527 /* clear */
2528 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2529 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2530 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2531 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2532 if (csid_reg->cmn_reg->no_pix)
2533 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2534 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2535
2536 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2537 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2538 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2539 }
2540 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2541 csid_reg->cmn_reg->csid_irq_cmd_addr);
2542
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002543 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2544 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Jing Zhouff57d862017-03-21 00:54:25 -07002545
2546 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002547 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002548 complete(&csid_hw->csid_top_complete);
2549 return IRQ_HANDLED;
2550 }
2551
2552
2553 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002554 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002555 complete(&csid_hw->csid_csi2_complete);
2556 }
2557
2558 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002559 pr_err_ratelimited("CSID:%d lane 0 over flow",
2560 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002561 }
2562 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002563 pr_err_ratelimited("CSID:%d lane 1 over flow",
2564 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002565 }
2566 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002567 pr_err_ratelimited("CSID:%d lane 2 over flow",
2568 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002569 }
2570 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002571 pr_err_ratelimited("CSID:%d lane 3 over flow",
2572 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002573 }
2574 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002575 pr_err_ratelimited("CSID:%d TG OVER FLOW",
2576 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002577 }
2578 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002579 pr_err_ratelimited("CSID:%d CPHY_EOT_RECEPTION",
2580 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002581 }
2582 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002583 pr_err_ratelimited("CSID:%d CPHY_SOT_RECEPTION",
2584 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002585 }
2586 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002587 pr_err_ratelimited("CSID:%d CPHY_PH_CRC",
2588 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002589 }
2590
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302591 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
2592 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
2593 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_EOT_CAPTURED",
2594 csid_hw->hw_intf->hw_idx);
2595 }
2596 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED) {
2597 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_EOT_CAPTURED",
2598 csid_hw->hw_intf->hw_idx);
2599 }
2600 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED) {
2601 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_EOT_CAPTURED",
2602 csid_hw->hw_intf->hw_idx);
2603 }
2604 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED) {
2605 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_EOT_CAPTURED",
2606 csid_hw->hw_intf->hw_idx);
2607 }
2608 }
2609
2610 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) {
2611 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED) {
2612 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_SOT_CAPTURED",
2613 csid_hw->hw_intf->hw_idx);
2614 }
2615 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED) {
2616 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_SOT_CAPTURED",
2617 csid_hw->hw_intf->hw_idx);
2618 }
2619 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED) {
2620 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_SOT_CAPTURED",
2621 csid_hw->hw_intf->hw_idx);
2622 }
2623 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED) {
2624 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_SOT_CAPTURED",
2625 csid_hw->hw_intf->hw_idx);
2626 }
2627 }
2628
2629 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) &&
2630 (irq_status_rx & CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED)) {
2631 CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
2632 csid_hw->hw_intf->hw_idx);
2633 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2634 csid_reg->csi2_reg->
2635 csid_csi2_rx_captured_long_pkt_0_addr);
2636 CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
2637 csid_hw->hw_intf->hw_idx,
2638 (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
2639 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2640 csid_reg->csi2_reg->
2641 csid_csi2_rx_captured_long_pkt_1_addr);
2642 CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
2643 csid_hw->hw_intf->hw_idx, val);
2644 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2645 csid_reg->csi2_reg->
2646 csid_csi2_rx_captured_long_pkt_ftr_addr);
2647 CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
2648 csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
2649 }
2650 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) &&
2651 (irq_status_rx & CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED)) {
2652 CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
2653 csid_hw->hw_intf->hw_idx);
2654 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2655 csid_reg->csi2_reg->
2656 csid_csi2_rx_captured_short_pkt_0_addr);
2657 CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
2658 csid_hw->hw_intf->hw_idx,
2659 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2660 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2661 csid_reg->csi2_reg->
2662 csid_csi2_rx_captured_short_pkt_1_addr);
2663 CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d", val);
2664 }
2665
2666 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
2667 (irq_status_rx & CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED)) {
2668 CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
2669 csid_hw->hw_intf->hw_idx);
2670 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2671 csid_reg->csi2_reg->
2672 csid_csi2_rx_captured_cphy_pkt_hdr_addr);
2673 CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
2674 csid_hw->hw_intf->hw_idx,
2675 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2676 }
2677
Jing Zhouff57d862017-03-21 00:54:25 -07002678 /*read the IPP errors */
2679 if (csid_reg->cmn_reg->no_pix) {
2680 /* IPP reset done bit */
2681 if (irq_status_ipp &
2682 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002683 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002684 complete(&csid_hw->csid_ipp_complete);
2685 }
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302686 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
2687 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2688 CAM_ERR(CAM_ISP, "CSID:%d IPP SOF received",
2689 csid_hw->hw_intf->hw_idx);
2690
2691 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
2692 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2693 CAM_ERR(CAM_ISP, "CSID:%d IPP EOF received",
2694 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002695
2696 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2697 complete(&csid_hw->csid_ipp_complete);
2698
2699 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002700 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002701 csid_hw->hw_intf->hw_idx);
2702 /*Stop IPP path immediately */
2703 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2704 soc_info->reg_map[0].mem_base +
2705 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2706 }
2707 }
2708
2709 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2710 if (irq_status_rdi[i] &
2711 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302712 CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002713 complete(&csid_hw->csid_rdin_complete[i]);
2714 }
2715
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302716 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
2717 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2718 CAM_ERR(CAM_ISP, "CSID RDI:%d SOF received", i);
2719
2720 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) &&
2721 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2722 CAM_ERR(CAM_ISP, "CSID RDI:%d EOF received", i);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302723
Jing Zhouff57d862017-03-21 00:54:25 -07002724 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2725 complete(&csid_hw->csid_rdin_complete[i]);
2726
2727 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002728 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002729 csid_hw->hw_intf->hw_idx);
2730 /*Stop RDI path immediately */
2731 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2732 soc_info->reg_map[0].mem_base +
2733 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2734 }
2735 }
2736
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002737 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002738 return IRQ_HANDLED;
2739}
2740
2741int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2742 uint32_t csid_idx)
2743{
2744 int rc = -EINVAL;
2745 uint32_t i;
2746 struct cam_ife_csid_path_cfg *path_data;
2747 struct cam_ife_csid_cid_data *cid_data;
2748 struct cam_hw_info *csid_hw_info;
2749 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2750
2751 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002752 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002753 return rc;
2754 }
2755
2756 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2757 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2758
2759 ife_csid_hw->hw_intf = csid_hw_intf;
2760 ife_csid_hw->hw_info = csid_hw_info;
2761
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002762 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002763 ife_csid_hw->hw_intf->hw_type, csid_idx);
2764
2765
2766 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2767 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2768 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2769 init_completion(&ife_csid_hw->hw_info->hw_complete);
2770
2771 init_completion(&ife_csid_hw->csid_top_complete);
2772 init_completion(&ife_csid_hw->csid_csi2_complete);
2773 init_completion(&ife_csid_hw->csid_ipp_complete);
2774 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2775 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2776
2777
2778 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2779 cam_ife_csid_irq, ife_csid_hw);
2780 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002781 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002782 goto err;
2783 }
2784
2785 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2786 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2787 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2788 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2789 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2790 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2791 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2792 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2793 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2794 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2795 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2796
2797 /*Initialize the CID resoure */
2798 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2799 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2800 ife_csid_hw->cid_res[i].res_id = i;
2801 ife_csid_hw->cid_res[i].res_state =
2802 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2803 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2804
2805 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2806 GFP_KERNEL);
2807 if (!cid_data) {
2808 rc = -ENOMEM;
2809 goto err;
2810 }
2811 ife_csid_hw->cid_res[i].res_priv = cid_data;
2812 }
2813
2814 /* Initialize the IPP resources */
2815 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2816 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2817 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2818 ife_csid_hw->ipp_res.res_state =
2819 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2820 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2821 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2822 GFP_KERNEL);
2823 if (!path_data) {
2824 rc = -ENOMEM;
2825 goto err;
2826 }
2827 ife_csid_hw->ipp_res.res_priv = path_data;
2828 }
2829
2830 /* Initialize the RDI resource */
2831 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2832 i++) {
2833 /* res type is from RDI 0 to RDI3 */
2834 ife_csid_hw->rdi_res[i].res_type =
2835 CAM_ISP_RESOURCE_PIX_PATH;
2836 ife_csid_hw->rdi_res[i].res_id = i;
2837 ife_csid_hw->rdi_res[i].res_state =
2838 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2839 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2840
2841 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2842 GFP_KERNEL);
2843 if (!path_data) {
2844 rc = -ENOMEM;
2845 goto err;
2846 }
2847 ife_csid_hw->rdi_res[i].res_priv = path_data;
2848 }
2849
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302850 ife_csid_hw->csid_debug = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07002851 return 0;
2852err:
2853 if (rc) {
2854 kfree(ife_csid_hw->ipp_res.res_priv);
2855 for (i = 0; i <
2856 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2857 kfree(ife_csid_hw->rdi_res[i].res_priv);
2858
2859 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2860 kfree(ife_csid_hw->cid_res[i].res_priv);
2861
2862 }
2863
2864 return rc;
2865}
2866
2867
2868int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2869{
2870 int rc = -EINVAL;
2871 uint32_t i;
2872
2873 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002874 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002875 return rc;
2876 }
2877
2878 /* release the privdate data memory from resources */
2879 kfree(ife_csid_hw->ipp_res.res_priv);
2880 for (i = 0; i <
2881 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2882 i++) {
2883 kfree(ife_csid_hw->rdi_res[i].res_priv);
2884 }
2885 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2886 kfree(ife_csid_hw->cid_res[i].res_priv);
2887
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302888 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07002889
2890 return 0;
2891}