blob: c5dd6ffd27f63a60f746a6e36599d257343c3e7a [file] [log] [blame]
Jing Zhouff57d862017-03-21 00:54:25 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/iopoll.h>
14#include <linux/slab.h>
15#include <uapi/media/cam_isp.h>
16#include <uapi/media/cam_defs.h>
17
18#include "cam_ife_csid_core.h"
19#include "cam_isp_hw.h"
20#include "cam_soc_util.h"
21#include "cam_io_util.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070022#include "cam_debug_util.h"
Jing Zhouff57d862017-03-21 00:54:25 -070023
24/* Timeout value in msec */
25#define IFE_CSID_TIMEOUT 1000
26
27/* TPG VC/DT values */
28#define CAM_IFE_CSID_TPG_VC_VAL 0xA
29#define CAM_IFE_CSID_TPG_DT_VAL 0x2B
30
31/* Timeout values in usec */
32#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
33#define CAM_IFE_CSID_TIMEOUT_ALL_US 1000000
34
35static int cam_ife_csid_is_ipp_format_supported(
Harsh Shahf7136392017-08-29 12:42:52 -070036 uint32_t in_format)
Jing Zhouff57d862017-03-21 00:54:25 -070037{
38 int rc = -EINVAL;
39
Harsh Shahf7136392017-08-29 12:42:52 -070040 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070041 case CAM_FORMAT_MIPI_RAW_6:
42 case CAM_FORMAT_MIPI_RAW_8:
43 case CAM_FORMAT_MIPI_RAW_10:
44 case CAM_FORMAT_MIPI_RAW_12:
45 case CAM_FORMAT_MIPI_RAW_14:
46 case CAM_FORMAT_MIPI_RAW_16:
47 case CAM_FORMAT_MIPI_RAW_20:
48 case CAM_FORMAT_DPCM_10_6_10:
49 case CAM_FORMAT_DPCM_10_8_10:
50 case CAM_FORMAT_DPCM_12_6_12:
51 case CAM_FORMAT_DPCM_12_8_12:
52 case CAM_FORMAT_DPCM_14_8_14:
53 case CAM_FORMAT_DPCM_14_10_14:
54 rc = 0;
55 break;
56 default:
57 break;
58 }
59 return rc;
60}
61
Harsh Shahf7136392017-08-29 12:42:52 -070062static int cam_ife_csid_get_format_rdi(
63 uint32_t in_format, uint32_t out_format,
64 uint32_t *decode_fmt, uint32_t *plain_fmt)
Jing Zhouff57d862017-03-21 00:54:25 -070065{
66 int rc = 0;
67
Harsh Shahf7136392017-08-29 12:42:52 -070068 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070069 case CAM_FORMAT_MIPI_RAW_6:
Harsh Shahf7136392017-08-29 12:42:52 -070070 switch (out_format) {
71 case CAM_FORMAT_MIPI_RAW_6:
72 *decode_fmt = 0xf;
73 break;
74 case CAM_FORMAT_PLAIN8:
75 *decode_fmt = 0x0;
76 *plain_fmt = 0x0;
77 break;
78 default:
79 rc = -EINVAL;
80 break;
81 }
Jing Zhouff57d862017-03-21 00:54:25 -070082 break;
83 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahf7136392017-08-29 12:42:52 -070084 switch (out_format) {
85 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahea34b602017-09-29 11:42:45 -070086 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -070087 *decode_fmt = 0xf;
88 break;
89 case CAM_FORMAT_PLAIN8:
90 *decode_fmt = 0x1;
91 *plain_fmt = 0x0;
92 break;
93 default:
94 rc = -EINVAL;
95 break;
96 }
Jing Zhouff57d862017-03-21 00:54:25 -070097 break;
98 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -070099 switch (out_format) {
100 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahea34b602017-09-29 11:42:45 -0700101 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700102 *decode_fmt = 0xf;
103 break;
104 case CAM_FORMAT_PLAIN16_10:
105 *decode_fmt = 0x2;
106 *plain_fmt = 0x1;
107 break;
108 default:
109 rc = -EINVAL;
110 break;
111 }
Jing Zhouff57d862017-03-21 00:54:25 -0700112 break;
113 case CAM_FORMAT_MIPI_RAW_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700114 switch (out_format) {
115 case CAM_FORMAT_MIPI_RAW_12:
116 *decode_fmt = 0xf;
117 break;
118 case CAM_FORMAT_PLAIN16_12:
119 *decode_fmt = 0x3;
120 *plain_fmt = 0x1;
121 break;
122 default:
123 rc = -EINVAL;
124 break;
125 }
Jing Zhouff57d862017-03-21 00:54:25 -0700126 break;
127 case CAM_FORMAT_MIPI_RAW_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700128 switch (out_format) {
129 case CAM_FORMAT_MIPI_RAW_14:
130 *decode_fmt = 0xf;
131 break;
132 case CAM_FORMAT_PLAIN16_14:
133 *decode_fmt = 0x4;
134 *plain_fmt = 0x1;
135 break;
136 default:
137 rc = -EINVAL;
138 break;
139 }
Jing Zhouff57d862017-03-21 00:54:25 -0700140 break;
141 case CAM_FORMAT_MIPI_RAW_16:
Harsh Shahf7136392017-08-29 12:42:52 -0700142 switch (out_format) {
143 case CAM_FORMAT_MIPI_RAW_16:
144 *decode_fmt = 0xf;
145 break;
146 case CAM_FORMAT_PLAIN16_16:
147 *decode_fmt = 0x5;
148 *plain_fmt = 0x1;
149 break;
150 default:
151 rc = -EINVAL;
152 break;
153 }
Jing Zhouff57d862017-03-21 00:54:25 -0700154 break;
155 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahf7136392017-08-29 12:42:52 -0700156 switch (out_format) {
157 case CAM_FORMAT_MIPI_RAW_20:
158 *decode_fmt = 0xf;
159 break;
160 case CAM_FORMAT_PLAIN32_20:
161 *decode_fmt = 0x6;
162 *plain_fmt = 0x2;
163 break;
164 default:
165 rc = -EINVAL;
166 break;
167 }
Jing Zhouff57d862017-03-21 00:54:25 -0700168 break;
169 case CAM_FORMAT_DPCM_10_6_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700170 *decode_fmt = 0x7;
171 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700172 break;
173 case CAM_FORMAT_DPCM_10_8_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700174 *decode_fmt = 0x8;
175 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700176 break;
177 case CAM_FORMAT_DPCM_12_6_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700178 *decode_fmt = 0x9;
179 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700180 break;
181 case CAM_FORMAT_DPCM_12_8_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700182 *decode_fmt = 0xA;
183 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700184 break;
185 case CAM_FORMAT_DPCM_14_8_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700186 *decode_fmt = 0xB;
187 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700188 break;
189 case CAM_FORMAT_DPCM_14_10_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700190 *decode_fmt = 0xC;
191 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700192 break;
193 default:
Harsh Shahf7136392017-08-29 12:42:52 -0700194 rc = -EINVAL;
195 break;
196 }
197
198 if (rc)
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530199 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d",
Harsh Shahf7136392017-08-29 12:42:52 -0700200 in_format, out_format);
201
202 return rc;
203}
204
205static int cam_ife_csid_get_format_ipp(
206 uint32_t in_format,
207 uint32_t *decode_fmt, uint32_t *plain_fmt)
208{
209 int rc = 0;
210
211 CAM_DBG(CAM_ISP, "input format:%d",
212 in_format);
213
214 switch (in_format) {
215 case CAM_FORMAT_MIPI_RAW_6:
216 *decode_fmt = 0;
217 *plain_fmt = 0;
218 break;
219 case CAM_FORMAT_MIPI_RAW_8:
220 *decode_fmt = 0x1;
221 *plain_fmt = 0;
222 break;
223 case CAM_FORMAT_MIPI_RAW_10:
224 *decode_fmt = 0x2;
225 *plain_fmt = 0x1;
226 break;
227 case CAM_FORMAT_MIPI_RAW_12:
228 *decode_fmt = 0x3;
229 *plain_fmt = 0x1;
230 break;
231 case CAM_FORMAT_MIPI_RAW_14:
232 *decode_fmt = 0x4;
233 *plain_fmt = 0x1;
234 break;
235 case CAM_FORMAT_MIPI_RAW_16:
236 *decode_fmt = 0x5;
237 *plain_fmt = 0x1;
238 break;
239 case CAM_FORMAT_MIPI_RAW_20:
240 *decode_fmt = 0x6;
241 *plain_fmt = 0x2;
242 break;
243 case CAM_FORMAT_DPCM_10_6_10:
244 *decode_fmt = 0x7;
245 *plain_fmt = 0x1;
246 break;
247 case CAM_FORMAT_DPCM_10_8_10:
248 *decode_fmt = 0x8;
249 *plain_fmt = 0x1;
250 break;
251 case CAM_FORMAT_DPCM_12_6_12:
252 *decode_fmt = 0x9;
253 *plain_fmt = 0x1;
254 break;
255 case CAM_FORMAT_DPCM_12_8_12:
256 *decode_fmt = 0xA;
257 *plain_fmt = 0x1;
258 break;
259 case CAM_FORMAT_DPCM_14_8_14:
260 *decode_fmt = 0xB;
261 *plain_fmt = 0x1;
262 break;
263 case CAM_FORMAT_DPCM_14_10_14:
264 *decode_fmt = 0xC;
265 *plain_fmt = 0x1;
266 break;
267 default:
268 CAM_ERR(CAM_ISP, "Unsupported format %d",
269 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700270 rc = -EINVAL;
271 }
272
Harsh Shahf7136392017-08-29 12:42:52 -0700273 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
274 *decode_fmt, *plain_fmt);
275
Jing Zhouff57d862017-03-21 00:54:25 -0700276 return rc;
277}
278
279static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
280 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
281 uint32_t res_type)
282{
283 int rc = 0;
284 struct cam_ife_csid_cid_data *cid_data;
285 uint32_t i = 0, j = 0;
286
287 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
288 if (csid_hw->cid_res[i].res_state >=
289 CAM_ISP_RESOURCE_STATE_RESERVED) {
290 cid_data = (struct cam_ife_csid_cid_data *)
291 csid_hw->cid_res[i].res_priv;
292 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
293 if (cid_data->tpg_set) {
294 cid_data->cnt++;
295 *res = &csid_hw->cid_res[i];
296 break;
297 }
298 } else {
299 if (cid_data->vc == vc && cid_data->dt == dt) {
300 cid_data->cnt++;
301 *res = &csid_hw->cid_res[i];
302 break;
303 }
304 }
305 }
306 }
307
308 if (i == CAM_IFE_CSID_CID_RES_MAX) {
309 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700310 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
311 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700312 rc = -EINVAL;
313 }
314
315 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
316 if (csid_hw->cid_res[j].res_state ==
317 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
318 cid_data = (struct cam_ife_csid_cid_data *)
319 csid_hw->cid_res[j].res_priv;
320 cid_data->vc = vc;
321 cid_data->dt = dt;
322 cid_data->cnt = 1;
323 csid_hw->cid_res[j].res_state =
324 CAM_ISP_RESOURCE_STATE_RESERVED;
325 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700326 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700327 csid_hw->hw_intf->hw_idx,
328 csid_hw->cid_res[j].res_id);
329 break;
330 }
331 }
332
333 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700334 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
335 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700336 rc = -EINVAL;
337 }
338 }
339
340 return rc;
341}
342
343
344static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
345{
346 struct cam_hw_soc_info *soc_info;
347 struct cam_ife_csid_reg_offset *csid_reg;
348 int rc = 0;
349 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
350 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
351
352 soc_info = &csid_hw->hw_info->soc_info;
353 csid_reg = csid_hw->csid_info->csid_reg;
354
355 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700356 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
357 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700358 csid_hw->hw_info->hw_state);
359 return -EINVAL;
360 }
361
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700362 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700363 csid_hw->hw_intf->hw_idx);
364
365 init_completion(&csid_hw->csid_top_complete);
366
367 /* Save interrupt mask registers values*/
368 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
369 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
370
371 if (csid_reg->cmn_reg->no_pix)
372 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
373 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
374
375 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
376 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
377 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
378 }
379
380 /* Mask all interrupts */
381 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
382 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
383
384 if (csid_reg->cmn_reg->no_pix)
385 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
386 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
387
388 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
389 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
390 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
391
392 /* clear all interrupts */
393 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
394 csid_reg->cmn_reg->csid_top_irq_clear_addr);
395
396 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
397 soc_info->reg_map[0].mem_base +
398 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
399
400 if (csid_reg->cmn_reg->no_pix)
401 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
402 soc_info->reg_map[0].mem_base +
403 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
404
405 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
406 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
407 soc_info->reg_map[0].mem_base +
408 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
409
410 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
411 csid_reg->cmn_reg->csid_irq_cmd_addr);
412
413 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
414 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
415
416 /* enable the IPP and RDI format measure */
417 if (csid_reg->cmn_reg->no_pix)
418 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
419 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
420
421 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
422 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
423 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
424
425 /* perform the top CSID HW reset */
426 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
427 soc_info->reg_map[0].mem_base +
428 csid_reg->cmn_reg->csid_rst_strobes_addr);
429
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700430 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700431 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
432 msecs_to_jiffies(IFE_CSID_TIMEOUT));
433 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700434 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
435 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700436 if (rc == 0)
437 rc = -ETIMEDOUT;
438 } else {
439 rc = 0;
440 }
441
442 /*restore all interrupt masks */
443 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
444 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
445
446 if (csid_reg->cmn_reg->no_pix)
447 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
448 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
449
450 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
451 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
452 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
453
454 return rc;
455}
456
457static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
458 struct cam_csid_reset_cfg_args *reset)
459{
460 int rc = 0;
461 struct cam_hw_soc_info *soc_info;
462 struct cam_isp_resource_node *res;
463 struct cam_ife_csid_reg_offset *csid_reg;
464 uint32_t reset_strb_addr, reset_strb_val, val, id;
465 struct completion *complete;
466
467 csid_reg = csid_hw->csid_info->csid_reg;
468 soc_info = &csid_hw->hw_info->soc_info;
469 res = reset->node_res;
470
471 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700472 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
473 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700474 csid_hw->hw_info->hw_state);
475 return -EINVAL;
476 }
477
478 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700479 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
480 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700481 rc = -EINVAL;
482 goto end;
483 }
484
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700485 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700486 csid_hw->hw_intf->hw_idx, res->res_id);
487
488 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
489 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700490 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
491 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700492 res->res_id);
493 return -EINVAL;
494 }
495
496 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
497 complete = &csid_hw->csid_ipp_complete;
498
499 /* Enable path reset done interrupt */
500 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
501 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
502 val |= CSID_PATH_INFO_RST_DONE;
503 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
504 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
505
506 } else {
507 id = res->res_id;
508 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700509 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
510 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700511 res->res_id);
512 return -EINVAL;
513 }
514
515 reset_strb_addr =
516 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
517 complete =
518 &csid_hw->csid_rdin_complete[id];
519
520 /* Enable path reset done interrupt */
521 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
522 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
523 val |= CSID_PATH_INFO_RST_DONE;
524 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
525 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
526 }
527
528 init_completion(complete);
529 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
530
531 /* Enable the Test gen before reset */
532 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
533 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
534
535 /* Reset the corresponding ife csid path */
536 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
537 reset_strb_addr);
538
539 rc = wait_for_completion_timeout(complete,
540 msecs_to_jiffies(IFE_CSID_TIMEOUT));
541 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700542 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
543 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700544 res->res_id, rc);
545 if (rc == 0)
546 rc = -ETIMEDOUT;
547 }
548
549 /* Disable Test Gen after reset*/
550 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
551 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
552
553end:
554 return rc;
555
556}
557
558static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
559 struct cam_csid_hw_reserve_resource_args *cid_reserv)
560{
561 int rc = 0;
562 struct cam_ife_csid_cid_data *cid_data;
563
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700564 CAM_DBG(CAM_ISP,
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530565 "CSID:%d res_sel:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700566 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700567 cid_reserv->in_port->res_type,
568 cid_reserv->in_port->lane_type,
569 cid_reserv->in_port->lane_num,
570 cid_reserv->in_port->dt,
571 cid_reserv->in_port->vc);
572
573 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700574 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
575 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700576 cid_reserv->in_port->res_type);
577 rc = -EINVAL;
578 goto end;
579 }
580
581 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
582 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700583 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
584 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700585 cid_reserv->in_port->lane_type);
586 rc = -EINVAL;
587 goto end;
588 }
589
590 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
591 cid_reserv->in_port->lane_num > 4) &&
592 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700593 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
594 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700595 cid_reserv->in_port->lane_num);
596 rc = -EINVAL;
597 goto end;
598 }
599 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
600 cid_reserv->in_port->lane_num > 3) &&
601 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700602 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
603 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700604 cid_reserv->in_port->lane_type,
605 cid_reserv->in_port->lane_num);
606 rc = -EINVAL;
607 goto end;
608 }
609
610 /* CSID CSI2 v2.0 supports 31 vc */
611 if (cid_reserv->in_port->dt > 0x3f ||
612 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700613 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
614 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700615 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
616 rc = -EINVAL;
617 goto end;
618 }
619
620 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
621 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
622 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700623 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
624 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700625 cid_reserv->in_port->format);
626 rc = -EINVAL;
627 goto end;
628 }
629
Harsh Shah398b0122017-09-28 15:36:39 -0700630 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_PHY_3 &&
631 csid_hw->hw_intf->hw_idx != 2) {
632 rc = -EINVAL;
633 goto end;
634 }
635
Jing Zhouff57d862017-03-21 00:54:25 -0700636 if (csid_hw->csi2_reserve_cnt) {
637 /* current configure res type should match requested res type */
638 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
639 rc = -EINVAL;
640 goto end;
641 }
642
643 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
644 if (csid_hw->csi2_rx_cfg.lane_cfg !=
645 cid_reserv->in_port->lane_cfg ||
646 csid_hw->csi2_rx_cfg.lane_type !=
647 cid_reserv->in_port->lane_type ||
648 csid_hw->csi2_rx_cfg.lane_num !=
649 cid_reserv->in_port->lane_num) {
650 rc = -EINVAL;
651 goto end;
652 }
653 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700654 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700655 cid_reserv->in_port->format ||
656 csid_hw->tpg_cfg.width !=
657 cid_reserv->in_port->left_width ||
658 csid_hw->tpg_cfg.height !=
659 cid_reserv->in_port->height ||
660 csid_hw->tpg_cfg.test_pattern !=
661 cid_reserv->in_port->test_pattern) {
662 rc = -EINVAL;
663 goto end;
664 }
665 }
666 }
667
668 if (!csid_hw->csi2_reserve_cnt) {
669 csid_hw->res_type = cid_reserv->in_port->res_type;
670 /* Take the first CID resource*/
671 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
672 cid_data = (struct cam_ife_csid_cid_data *)
673 csid_hw->cid_res[0].res_priv;
674
675 csid_hw->csi2_rx_cfg.lane_cfg =
676 cid_reserv->in_port->lane_cfg;
677 csid_hw->csi2_rx_cfg.lane_type =
678 cid_reserv->in_port->lane_type;
679 csid_hw->csi2_rx_cfg.lane_num =
680 cid_reserv->in_port->lane_num;
681
682 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
683 csid_hw->csi2_rx_cfg.phy_sel = 0;
684 if (cid_reserv->in_port->format >
685 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700686 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700687 rc = -EINVAL;
688 goto end;
689 }
Harsh Shahf7136392017-08-29 12:42:52 -0700690 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700691 cid_reserv->in_port->format;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530692 csid_hw->tpg_cfg.usage_type =
693 cid_reserv->in_port->usage_type;
694 if (cid_reserv->in_port->usage_type)
695 csid_hw->tpg_cfg.width =
696 (cid_reserv->in_port->right_stop + 1);
697 else
698 csid_hw->tpg_cfg.width =
699 cid_reserv->in_port->left_width;
700
Jing Zhouff57d862017-03-21 00:54:25 -0700701 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
702 csid_hw->tpg_cfg.test_pattern =
703 cid_reserv->in_port->test_pattern;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530704
705 CAM_DBG(CAM_ISP, "CSID:%d TPG width:%d height:%d",
706 csid_hw->hw_intf->hw_idx,
707 csid_hw->tpg_cfg.width,
708 csid_hw->tpg_cfg.height);
709
Jing Zhouff57d862017-03-21 00:54:25 -0700710 cid_data->tpg_set = 1;
711 } else {
712 csid_hw->csi2_rx_cfg.phy_sel =
713 (cid_reserv->in_port->res_type & 0xFF) - 1;
714 }
715
716 cid_data->vc = cid_reserv->in_port->vc;
717 cid_data->dt = cid_reserv->in_port->dt;
718 cid_data->cnt = 1;
719 cid_reserv->node_res = &csid_hw->cid_res[0];
720 csid_hw->csi2_reserve_cnt++;
721
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700722 CAM_DBG(CAM_ISP,
723 "CSID:%d CID :%d resource acquired successfully",
724 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700725 cid_reserv->node_res->res_id);
726 } else {
727 rc = cam_ife_csid_cid_get(csid_hw, &cid_reserv->node_res,
728 cid_reserv->in_port->vc, cid_reserv->in_port->dt,
729 cid_reserv->in_port->res_type);
730 /* if success then increment the reserve count */
731 if (!rc) {
732 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700733 CAM_ERR(CAM_ISP,
734 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700735 csid_hw->hw_intf->hw_idx);
736 rc = -EINVAL;
737 } else {
738 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700739 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700740 csid_hw->hw_intf->hw_idx,
741 cid_reserv->node_res->res_id);
742 }
743 }
744 }
745
746end:
747 return rc;
748}
749
750
751static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
752 struct cam_csid_hw_reserve_resource_args *reserve)
753{
754 int rc = 0;
755 struct cam_ife_csid_path_cfg *path_data;
756 struct cam_isp_resource_node *res;
757
758 /* CSID CSI2 v2.0 supports 31 vc */
759 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
760 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700761 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
762 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700763 reserve->in_port->vc, reserve->in_port->dt,
764 reserve->sync_mode);
765 rc = -EINVAL;
766 goto end;
767 }
768
769 switch (reserve->res_id) {
770 case CAM_IFE_PIX_PATH_RES_IPP:
771 if (csid_hw->ipp_res.res_state !=
772 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700773 CAM_DBG(CAM_ISP,
774 "CSID:%d IPP resource not available %d",
775 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700776 csid_hw->ipp_res.res_state);
777 rc = -EINVAL;
778 goto end;
779 }
780
781 if (cam_ife_csid_is_ipp_format_supported(
782 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700783 CAM_ERR(CAM_ISP,
784 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700785 csid_hw->hw_intf->hw_idx, reserve->res_id,
786 reserve->in_port->format);
787 rc = -EINVAL;
788 goto end;
789 }
790
791 /* assign the IPP resource */
792 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700793 CAM_DBG(CAM_ISP,
794 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700795 csid_hw->hw_intf->hw_idx, res->res_id);
796
797 break;
798 case CAM_IFE_PIX_PATH_RES_RDI_0:
799 case CAM_IFE_PIX_PATH_RES_RDI_1:
800 case CAM_IFE_PIX_PATH_RES_RDI_2:
801 case CAM_IFE_PIX_PATH_RES_RDI_3:
802 if (csid_hw->rdi_res[reserve->res_id].res_state !=
803 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700804 CAM_DBG(CAM_ISP,
805 "CSID:%d RDI:%d resource not available %d",
806 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700807 reserve->res_id,
808 csid_hw->rdi_res[reserve->res_id].res_state);
809 rc = -EINVAL;
810 goto end;
811 } else {
812 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700813 CAM_DBG(CAM_ISP,
814 "CSID:%d RDI resource:%d acquire success",
815 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700816 res->res_id);
817 }
818
819 break;
820 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700821 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700822 csid_hw->hw_intf->hw_idx, reserve->res_id);
823 rc = -EINVAL;
824 goto end;
825 }
826
827 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
828 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
829
830 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700831 path_data->in_format = reserve->in_port->format;
832 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700833 path_data->master_idx = reserve->master_idx;
834 path_data->sync_mode = reserve->sync_mode;
835 path_data->height = reserve->in_port->height;
836 path_data->start_line = reserve->in_port->line_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530837 path_data->end_line = reserve->in_port->line_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700838 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
839 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
840 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
841 } else {
842 path_data->dt = reserve->in_port->dt;
843 path_data->vc = reserve->in_port->vc;
844 }
845
846 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
847 path_data->crop_enable = 1;
848 path_data->start_pixel = reserve->in_port->left_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530849 path_data->end_pixel = reserve->in_port->left_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700850 path_data->width = reserve->in_port->left_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530851 CAM_DBG(CAM_ISP, "CSID:%dmaster:startpixel 0x%x endpixel:0x%x",
852 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
853 path_data->end_pixel);
854 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
855 csid_hw->hw_intf->hw_idx, path_data->start_line,
856 path_data->end_line);
Jing Zhouff57d862017-03-21 00:54:25 -0700857 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
858 path_data->crop_enable = 1;
859 path_data->start_pixel = reserve->in_port->right_start;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530860 path_data->end_pixel = reserve->in_port->right_stop;
Jing Zhouff57d862017-03-21 00:54:25 -0700861 path_data->width = reserve->in_port->right_width;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530862 CAM_DBG(CAM_ISP, "CSID:%d slave:start:0x%x end:0x%x width 0x%x",
863 csid_hw->hw_intf->hw_idx, path_data->start_pixel,
864 path_data->end_pixel, path_data->width);
865 CAM_DBG(CAM_ISP, "CSID:%dmaster:line start:0x%x line end:0x%x",
866 csid_hw->hw_intf->hw_idx, path_data->start_line,
867 path_data->end_line);
Harsh Shahf7136392017-08-29 12:42:52 -0700868 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700869 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700870 path_data->width = reserve->in_port->left_width;
871 path_data->start_pixel = reserve->in_port->left_start;
872 }
Jing Zhouff57d862017-03-21 00:54:25 -0700873
Ravikishore Pampanac19ba622017-09-21 17:20:48 +0530874 CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
Harsh Shahf7136392017-08-29 12:42:52 -0700875 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700876 reserve->node_res = res;
877
878end:
879 return rc;
880}
881
882static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
883{
884 int rc = 0;
885 struct cam_ife_csid_reg_offset *csid_reg;
886 struct cam_hw_soc_info *soc_info;
887 uint32_t i, status, val;
888
889 csid_reg = csid_hw->csid_info->csid_reg;
890 soc_info = &csid_hw->hw_info->soc_info;
891
892 /* overflow check before increment */
893 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700894 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
895 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700896 return -EINVAL;
897 }
898
899 /* Increment ref Count */
900 csid_hw->hw_info->open_count++;
901 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700902 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700903 return rc;
904 }
905
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700906 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700907 csid_hw->hw_intf->hw_idx);
908
909 rc = cam_ife_csid_enable_soc_resources(soc_info);
910 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700911 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700912 csid_hw->hw_intf->hw_idx);
913 goto err;
914 }
915
916
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700917 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700918 csid_hw->hw_intf->hw_idx);
919
920 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
921 /* Enable the top IRQ interrupt */
922 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
923 csid_reg->cmn_reg->csid_top_irq_mask_addr);
924
925 rc = cam_ife_csid_global_reset(csid_hw);
926 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700927 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
928 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700929 rc = -ETIMEDOUT;
930 goto disable_soc;
931 }
932
933 /*
934 * Reset the SW registers
935 * SW register reset also reset the mask irq, so poll the irq status
936 * to check the reset complete.
937 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700938 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700939 csid_hw->hw_intf->hw_idx);
940
941 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
942 soc_info->reg_map[0].mem_base +
943 csid_reg->cmn_reg->csid_rst_strobes_addr);
944
945 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
946 csid_reg->cmn_reg->csid_top_irq_status_addr,
947 status, (status & 0x1) == 0x1,
948 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
949 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700950 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700951 rc = -ETIMEDOUT;
952 goto disable_soc;
953 }
954
955 /* clear all interrupts */
956 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
957 csid_reg->cmn_reg->csid_top_irq_clear_addr);
958
959 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
960 soc_info->reg_map[0].mem_base +
961 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
962
963 if (csid_reg->cmn_reg->no_pix)
964 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
965 soc_info->reg_map[0].mem_base +
966 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
967
968 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
969 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
970 soc_info->reg_map[0].mem_base +
971 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
972
973 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
974 csid_reg->cmn_reg->csid_irq_cmd_addr);
975
976 /* Enable the top IRQ interrupt */
977 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
978 csid_reg->cmn_reg->csid_top_irq_mask_addr);
979
980 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
981 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700982 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -0700983 csid_hw->hw_intf->hw_idx, val);
984
985 return 0;
986
987disable_soc:
988 cam_ife_csid_disable_soc_resources(soc_info);
989 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
990err:
991 csid_hw->hw_info->open_count--;
992 return rc;
993}
994
995static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
996{
997 int rc = 0;
998 struct cam_hw_soc_info *soc_info;
999 struct cam_ife_csid_reg_offset *csid_reg;
1000
1001
1002 /* Decrement ref Count */
1003 if (csid_hw->hw_info->open_count)
1004 csid_hw->hw_info->open_count--;
1005 if (csid_hw->hw_info->open_count)
1006 return rc;
1007
1008 soc_info = &csid_hw->hw_info->soc_info;
1009 csid_reg = csid_hw->csid_info->csid_reg;
1010
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001011 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -07001012 csid_hw->hw_intf->hw_idx);
1013
1014 /*disable the top IRQ interrupt */
1015 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1016 csid_reg->cmn_reg->csid_top_irq_mask_addr);
1017
1018 rc = cam_ife_csid_disable_soc_resources(soc_info);
1019 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001020 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
1021 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001022
1023 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
1024 return rc;
1025}
1026
1027
1028static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
1029 struct cam_isp_resource_node *res)
1030{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301031 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001032 uint32_t val = 0;
1033 struct cam_hw_soc_info *soc_info;
1034
1035 csid_hw->tpg_start_cnt++;
1036 if (csid_hw->tpg_start_cnt == 1) {
1037 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001038 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1039 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001040
1041 soc_info = &csid_hw->hw_info->soc_info;
1042 {
1043 uint32_t val;
1044 uint32_t i;
1045 uint32_t base = 0x600;
1046
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001047 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001048 for (i = 0; i < 16; i++) {
1049 val = cam_io_r_mb(
1050 soc_info->reg_map[0].mem_base +
1051 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001052 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001053 (base + i*4), val);
1054 }
1055
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001056 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001057 base = 0x200;
1058 for (i = 0; i < 10; i++) {
1059 val = cam_io_r_mb(
1060 soc_info->reg_map[0].mem_base +
1061 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001062 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001063 (base + i*4), val);
1064 }
1065
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001066 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001067 base = 0x100;
1068 for (i = 0; i < 5; i++) {
1069 val = cam_io_r_mb(
1070 soc_info->reg_map[0].mem_base +
1071 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001072 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001073 (base + i*4), val);
1074 }
1075 }
1076
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301077 /* Enable the IFE force clock on for dual isp case */
1078 if (csid_hw->tpg_cfg.usage_type) {
1079 rc = cam_ife_csid_enable_ife_force_clock_on(soc_info,
1080 csid_hw->csid_info->csid_reg->tpg_reg->
1081 tpg_cpas_ife_reg_offset);
1082 if (rc)
1083 return rc;
1084 }
1085
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001086 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001087 val = (4 << 20);
1088 val |= (0x80 << 8);
1089 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1090 val |= 7;
1091 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1092 csid_hw->csid_info->csid_reg->tpg_reg->
1093 csid_tpg_ctrl_addr);
1094
1095 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001096 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001097 }
1098
1099 return 0;
1100}
1101
1102static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1103 struct cam_isp_resource_node *res)
1104{
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301105 int rc = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001106 struct cam_hw_soc_info *soc_info;
1107
1108 if (csid_hw->tpg_start_cnt)
1109 csid_hw->tpg_start_cnt--;
1110
1111 if (csid_hw->tpg_start_cnt)
1112 return 0;
1113
1114 soc_info = &csid_hw->hw_info->soc_info;
1115
1116 /* disable the TPG */
1117 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001118 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1119 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001120
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301121 /* Disable the IFE force clock on for dual isp case */
1122 if (csid_hw->tpg_cfg.usage_type)
1123 rc = cam_ife_csid_disable_ife_force_clock_on(soc_info,
1124 csid_hw->csid_info->csid_reg->tpg_reg->
1125 tpg_cpas_ife_reg_offset);
1126
Jing Zhouff57d862017-03-21 00:54:25 -07001127 /*stop the TPG */
1128 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1129 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1130 }
1131
1132 return 0;
1133}
1134
1135
1136static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1137 struct cam_isp_resource_node *res)
1138{
1139 struct cam_ife_csid_reg_offset *csid_reg;
1140 struct cam_hw_soc_info *soc_info;
1141 uint32_t val = 0;
1142
1143 csid_reg = csid_hw->csid_info->csid_reg;
1144 soc_info = &csid_hw->hw_info->soc_info;
1145
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001146 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1147 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001148
1149 /* configure one DT, infinite frames */
1150 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1151 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1152 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1153
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301154 /* vertical blanking count = 0x3FF, horzontal blanking count = 0x740*/
1155 val = (0x3FF << 12) | 0x740;
Jing Zhouff57d862017-03-21 00:54:25 -07001156 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1157 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1158
1159 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1160 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1161
1162 val = csid_hw->tpg_cfg.width << 16 |
1163 csid_hw->tpg_cfg.height;
1164 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1165 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1166
1167 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1168 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1169
1170 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001171 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001172 * it is one larger than the register spec format.
1173 */
Harsh Shahf7136392017-08-29 12:42:52 -07001174 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001175 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1176 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1177
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001178 /* static frame with split color bar */
1179 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001180 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1181 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1182 /* config pix pattern */
1183 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1184 soc_info->reg_map[0].mem_base +
1185 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1186
1187 return 0;
1188}
1189
1190static int cam_ife_csid_enable_csi2(
1191 struct cam_ife_csid_hw *csid_hw,
1192 struct cam_isp_resource_node *res)
1193{
1194 int rc = 0;
1195 struct cam_ife_csid_reg_offset *csid_reg;
1196 struct cam_hw_soc_info *soc_info;
1197 struct cam_ife_csid_cid_data *cid_data;
1198 uint32_t val = 0;
1199
1200 csid_reg = csid_hw->csid_info->csid_reg;
1201 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001202 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1203 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001204
1205 /* overflow check before increment */
1206 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001207 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1208 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001209 return -EINVAL;
1210 }
1211
1212 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1213
1214 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1215 csid_hw->csi2_cfg_cnt++;
1216 if (csid_hw->csi2_cfg_cnt > 1)
1217 return rc;
1218
1219 /* rx cfg0 */
1220 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1221 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1222 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001223 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001224 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1225 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1226
1227 /* rx cfg1*/
1228 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1229 /* if VC value is more than 3 than set full width of VC */
1230 if (cid_data->vc > 3)
1231 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1232
1233 /* enable packet ecc correction */
1234 val |= 1;
1235 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1236 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1237
1238 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1239 /* Config the TPG */
1240 rc = cam_ife_csid_config_tpg(csid_hw, res);
1241 if (rc) {
1242 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1243 return rc;
1244 }
1245 }
1246
1247 /*Enable the CSI2 rx inerrupts */
1248 val = CSID_CSI2_RX_INFO_RST_DONE |
1249 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1250 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1251 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1252 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1253 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1254 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1255 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
1256 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301257
1258 /* Enable the interrupt based on csid debug info set */
1259 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ)
1260 val |= CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED |
1261 CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED |
1262 CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED |
1263 CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED;
1264
1265 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ)
1266 val |= CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED |
1267 CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED |
1268 CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED |
1269 CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED;
1270
1271 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1272 val |= CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED;
1273
1274 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1275 val |= CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED;
1276 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1277 val |= CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED;
1278
Jing Zhouff57d862017-03-21 00:54:25 -07001279 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1280 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1281
1282 return 0;
1283}
1284
1285static int cam_ife_csid_disable_csi2(
1286 struct cam_ife_csid_hw *csid_hw,
1287 struct cam_isp_resource_node *res)
1288{
1289 struct cam_ife_csid_reg_offset *csid_reg;
1290 struct cam_hw_soc_info *soc_info;
1291
1292 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001293 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1294 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001295 return -EINVAL;
1296 }
1297
1298 csid_reg = csid_hw->csid_info->csid_reg;
1299 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001300 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1301 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001302
1303 if (csid_hw->csi2_cfg_cnt)
1304 csid_hw->csi2_cfg_cnt--;
1305
1306 if (csid_hw->csi2_cfg_cnt)
1307 return 0;
1308
1309 /*Disable the CSI2 rx inerrupts */
1310 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1311 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1312
1313 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1314
1315 return 0;
1316}
1317
1318static int cam_ife_csid_init_config_ipp_path(
1319 struct cam_ife_csid_hw *csid_hw,
1320 struct cam_isp_resource_node *res)
1321{
1322 int rc = 0;
1323 struct cam_ife_csid_path_cfg *path_data;
1324 struct cam_ife_csid_reg_offset *csid_reg;
1325 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001326 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001327
1328 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1329 csid_reg = csid_hw->csid_info->csid_reg;
1330 soc_info = &csid_hw->hw_info->soc_info;
1331
1332 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001333 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1334 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001335 res->res_id);
1336 return -EINVAL;
1337 }
1338
Harsh Shahf7136392017-08-29 12:42:52 -07001339 CAM_DBG(CAM_ISP, "Config IPP Path");
1340 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1341 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001342 if (rc)
1343 return rc;
1344
Jing Zhoubb536a82017-05-18 15:20:38 -07001345 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001346 * configure the IPP and enable the time stamp capture.
1347 * enable the HW measrurement blocks
1348 */
1349 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1350 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1351 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001352 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301353 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001354 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301355 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001356 csid_reg->cmn_reg->crop_v_en_shift_val) |
1357 (1 << 1) | 1;
1358 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1359 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1360 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1361
Jing Zhoudedc4762017-06-19 17:45:36 +05301362 /* select the post irq sub sample strobe for time stamp capture */
1363 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1364 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1365
Jing Zhouff57d862017-03-21 00:54:25 -07001366 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301367 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001368 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301369 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001370 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1371 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301372 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1373 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001374
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301375 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001376 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301377 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001378 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1379 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301380 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1381 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001382 }
1383
1384 /* set frame drop pattern to 0 and period to 1 */
1385 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1386 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1387 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1388 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1389 /* set irq sub sample pattern to 0 and period to 1 */
1390 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1391 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1392 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1393 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1394 /* set pixel drop pattern to 0 and period to 1 */
1395 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1396 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1397 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1398 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1399 /* set line drop pattern to 0 and period to 1 */
1400 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1401 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1402 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1403 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1404
1405 /*Set master or slave IPP */
1406 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1407 /*Set halt mode as master */
1408 val = CSID_HALT_MODE_MASTER << 2;
1409 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1410 /*Set halt mode as slave and set master idx */
1411 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1412 else
1413 /* Default is internal halt mode */
1414 val = 0;
1415
1416 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1417 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1418
1419 /* Enable the IPP path */
1420 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1421 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1422 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1423 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1424 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1425
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301426 /* configure the rx packet capture based on csid debug set */
1427 val = 0;
1428 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1429 val = ((1 <<
1430 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1431 (path_data->vc <<
1432 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1433
1434 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1435 val |= ((1 <<
1436 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1437 (path_data->dt <<
1438 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1439 (path_data->vc <<
1440 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1441
1442 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1443 val |= ((1 <<
1444 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1445 (path_data->dt <<
1446 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1447 (path_data->vc <<
1448 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1449
1450 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1451 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1452 CAM_DBG(CAM_ISP, "rx capture control value 0x%x", val);
1453
Jing Zhouff57d862017-03-21 00:54:25 -07001454 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1455
1456 return rc;
1457}
1458
1459static int cam_ife_csid_deinit_ipp_path(
1460 struct cam_ife_csid_hw *csid_hw,
1461 struct cam_isp_resource_node *res)
1462{
1463 int rc = 0;
1464 struct cam_ife_csid_reg_offset *csid_reg;
1465 struct cam_hw_soc_info *soc_info;
1466 uint32_t val = 0;
1467
1468 csid_reg = csid_hw->csid_info->csid_reg;
1469 soc_info = &csid_hw->hw_info->soc_info;
1470
1471 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001472 CAM_ERR(CAM_ISP,
1473 "CSID:%d Res type %d res_id:%d in wrong state %d",
1474 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001475 res->res_type, res->res_id, res->res_state);
1476 rc = -EINVAL;
1477 }
1478
1479 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001480 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1481 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001482 res->res_id);
1483 rc = -EINVAL;
1484 }
1485
1486 /* Disable the IPP path */
1487 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1488 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1489 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1490 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1491 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1492
1493 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1494 return rc;
1495}
1496
1497static int cam_ife_csid_enable_ipp_path(
1498 struct cam_ife_csid_hw *csid_hw,
1499 struct cam_isp_resource_node *res)
1500{
1501 struct cam_ife_csid_reg_offset *csid_reg;
1502 struct cam_hw_soc_info *soc_info;
1503 struct cam_ife_csid_path_cfg *path_data;
1504 uint32_t val = 0;
1505
1506 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1507 csid_reg = csid_hw->csid_info->csid_reg;
1508 soc_info = &csid_hw->hw_info->soc_info;
1509
1510 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001511 CAM_ERR(CAM_ISP,
1512 "CSID:%d res type:%d res_id:%d Invalid state%d",
1513 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001514 res->res_type, res->res_id, res->res_state);
1515 return -EINVAL;
1516 }
1517
1518 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001519 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1520 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001521 res->res_id);
1522 return -EINVAL;
1523 }
1524
Harsh Shahf7136392017-08-29 12:42:52 -07001525 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001526
Harsh Shahf7136392017-08-29 12:42:52 -07001527 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001528 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1529 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1530 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1531 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1532 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1533 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1534 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1535 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1536 soc_info->reg_map[0].mem_base +
1537 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1538 }
1539 /* for slave mode, not need to resume for slave device */
1540
1541 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301542 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301543
1544 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1545 val |= CSID_PATH_INFO_INPUT_SOF;
1546 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1547 val |= CSID_PATH_INFO_INPUT_EOF;
1548
Jing Zhouff57d862017-03-21 00:54:25 -07001549 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1550 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1551
1552 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1553
1554 return 0;
1555}
1556
1557static int cam_ife_csid_disable_ipp_path(
1558 struct cam_ife_csid_hw *csid_hw,
1559 struct cam_isp_resource_node *res,
1560 enum cam_ife_csid_halt_cmd stop_cmd)
1561{
1562 int rc = 0;
1563 struct cam_ife_csid_reg_offset *csid_reg;
1564 struct cam_hw_soc_info *soc_info;
1565 struct cam_ife_csid_path_cfg *path_data;
1566 uint32_t val = 0;
1567
1568 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1569 csid_reg = csid_hw->csid_info->csid_reg;
1570 soc_info = &csid_hw->hw_info->soc_info;
1571
1572 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001573 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1574 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001575 return -EINVAL;
1576 }
1577
1578 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1579 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001580 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1581 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001582 res->res_id, res->res_state);
1583 return rc;
1584 }
1585
1586 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001587 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1588 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001589 res->res_state);
1590 return -EINVAL;
1591 }
1592
1593 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001594 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1595 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001596 return -EINVAL;
1597 }
1598
1599 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1600 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001601 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1602 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001603 return -EINVAL;
1604 }
1605
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001606 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001607 csid_hw->hw_intf->hw_idx, res->res_id);
1608
1609 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1610 /* configure Halt */
1611 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1612 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1613 val &= ~0x3;
1614 val |= stop_cmd;
1615 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1616 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1617 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1618 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1619 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1620
1621 /* For slave mode, halt command should take it from master */
1622
1623 /* Enable the EOF interrupt for resume at boundary case */
1624 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1625 init_completion(&csid_hw->csid_ipp_complete);
1626 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1627 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1628 val |= CSID_PATH_INFO_INPUT_EOF;
1629 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1630 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1631 } else {
1632 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001633 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001634 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1635 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1636 }
1637
1638 return rc;
1639}
1640
1641
1642static int cam_ife_csid_init_config_rdi_path(
1643 struct cam_ife_csid_hw *csid_hw,
1644 struct cam_isp_resource_node *res)
1645{
1646 int rc = 0;
1647 struct cam_ife_csid_path_cfg *path_data;
1648 struct cam_ife_csid_reg_offset *csid_reg;
1649 struct cam_hw_soc_info *soc_info;
1650 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1651
1652 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1653 csid_reg = csid_hw->csid_info->csid_reg;
1654 soc_info = &csid_hw->hw_info->soc_info;
1655
1656 id = res->res_id;
1657 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001658 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1659 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001660 return -EINVAL;
1661 }
1662
Harsh Shahf7136392017-08-29 12:42:52 -07001663 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1664 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001665 if (rc)
1666 return rc;
1667
Jing Zhoubb536a82017-05-18 15:20:38 -07001668 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001669 * RDI path config and enable the time stamp capture
1670 * Enable the measurement blocks
1671 */
1672 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1673 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1674 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1675 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1676 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301677 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001678 csid_reg->cmn_reg->crop_h_en_shift_val) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301679 (path_data->crop_enable <<
Jing Zhouff57d862017-03-21 00:54:25 -07001680 csid_reg->cmn_reg->crop_v_en_shift_val) |
1681 (1 << 2) | 3;
1682
1683 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1684 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1685
Jing Zhoudedc4762017-06-19 17:45:36 +05301686 /* select the post irq sub sample strobe for time stamp capture */
1687 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1688 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1689
Jing Zhouff57d862017-03-21 00:54:25 -07001690 if (path_data->crop_enable) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301691 val = (((path_data->end_pixel & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001692 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301693 (path_data->start_pixel & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001694
1695 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1696 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301697 CAM_DBG(CAM_ISP, "CSID:%d Horizontal crop config val: 0x%x",
1698 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001699
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301700 val = (((path_data->end_line & 0xFFFF) <<
Jing Zhouff57d862017-03-21 00:54:25 -07001701 csid_reg->cmn_reg->crop_shift) |
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301702 (path_data->start_line & 0xFFFF));
Jing Zhouff57d862017-03-21 00:54:25 -07001703
1704 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1705 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301706 CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
1707 csid_hw->hw_intf->hw_idx, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001708 }
1709 /* set frame drop pattern to 0 and period to 1 */
1710 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1711 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1712 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1713 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1714 /* set IRQ sum sabmple */
1715 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1716 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1717 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1718 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1719
1720 /* set pixel drop pattern to 0 and period to 1 */
1721 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1722 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1723 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1724 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1725 /* set line drop pattern to 0 and period to 1 */
1726 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1727 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1728 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1729 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1730
1731 /* Configure the halt mode */
1732 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1733 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1734
1735 /* Enable the RPP path */
1736 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1737 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1738 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001739
Jing Zhouff57d862017-03-21 00:54:25 -07001740 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1741 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1742
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301743 /* configure the rx packet capture based on csid debug set */
1744 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE)
1745 val = ((1 <<
1746 csid_reg->csi2_reg->csi2_capture_short_pkt_en_shift) |
1747 (path_data->vc <<
1748 csid_reg->csi2_reg->csi2_capture_short_pkt_vc_shift));
1749
1750 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE)
1751 val |= ((1 <<
1752 csid_reg->csi2_reg->csi2_capture_long_pkt_en_shift) |
1753 (path_data->dt <<
1754 csid_reg->csi2_reg->csi2_capture_long_pkt_dt_shift) |
1755 (path_data->vc <<
1756 csid_reg->csi2_reg->csi2_capture_long_pkt_vc_shift));
1757
1758 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE)
1759 val |= ((1 <<
1760 csid_reg->csi2_reg->csi2_capture_cphy_pkt_en_shift) |
1761 (path_data->dt <<
1762 csid_reg->csi2_reg->csi2_capture_cphy_pkt_dt_shift) |
1763 (path_data->vc <<
1764 csid_reg->csi2_reg->csi2_capture_cphy_pkt_vc_shift));
1765 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1766 csid_reg->csi2_reg->csid_csi2_rx_capture_ctrl_addr);
1767
Jing Zhouff57d862017-03-21 00:54:25 -07001768 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1769
1770 return rc;
1771}
1772
1773static int cam_ife_csid_deinit_rdi_path(
1774 struct cam_ife_csid_hw *csid_hw,
1775 struct cam_isp_resource_node *res)
1776{
1777 int rc = 0;
1778 struct cam_ife_csid_reg_offset *csid_reg;
1779 struct cam_hw_soc_info *soc_info;
1780 uint32_t val = 0, id;
1781
1782 csid_reg = csid_hw->csid_info->csid_reg;
1783 soc_info = &csid_hw->hw_info->soc_info;
1784 id = res->res_id;
1785
1786 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1787 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1788 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001789 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1790 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001791 res->res_state);
1792 return -EINVAL;
1793 }
1794
1795 /* Disable the RDI path */
1796 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1797 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1798 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1799 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1800 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1801
1802 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1803 return rc;
1804}
1805
1806static int cam_ife_csid_enable_rdi_path(
1807 struct cam_ife_csid_hw *csid_hw,
1808 struct cam_isp_resource_node *res)
1809{
1810 struct cam_ife_csid_reg_offset *csid_reg;
1811 struct cam_hw_soc_info *soc_info;
1812 uint32_t id, val;
1813
1814 csid_reg = csid_hw->csid_info->csid_reg;
1815 soc_info = &csid_hw->hw_info->soc_info;
1816 id = res->res_id;
1817
1818 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1819 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1820 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001821 CAM_ERR(CAM_ISP,
1822 "CSID:%d invalid res type:%d res_id:%d state%d",
1823 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001824 res->res_type, res->res_id, res->res_state);
1825 return -EINVAL;
1826 }
1827
1828 /*resume at frame boundary */
1829 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1830 soc_info->reg_map[0].mem_base +
1831 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1832
1833 /* Enable the required RDI interrupts */
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301834 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
1835
1836 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
1837 val |= CSID_PATH_INFO_INPUT_SOF;
1838 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
1839 val |= CSID_PATH_INFO_INPUT_EOF;
1840
Jing Zhouff57d862017-03-21 00:54:25 -07001841 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1842 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1843
1844 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1845
1846 return 0;
1847}
1848
1849
1850static int cam_ife_csid_disable_rdi_path(
1851 struct cam_ife_csid_hw *csid_hw,
1852 struct cam_isp_resource_node *res,
1853 enum cam_ife_csid_halt_cmd stop_cmd)
1854{
1855 int rc = 0;
1856 struct cam_ife_csid_reg_offset *csid_reg;
1857 struct cam_hw_soc_info *soc_info;
1858 uint32_t val = 0, id;
1859
1860 csid_reg = csid_hw->csid_info->csid_reg;
1861 soc_info = &csid_hw->hw_info->soc_info;
1862 id = res->res_id;
1863
1864 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1865 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001866 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1867 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001868 return -EINVAL;
1869 }
1870
1871 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1872 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001873 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1874 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001875 res->res_id, res->res_state);
1876 return rc;
1877 }
1878
1879 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001880 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1881 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001882 res->res_state);
1883 return -EINVAL;
1884 }
1885
1886 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1887 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001888 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1889 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001890 return -EINVAL;
1891 }
1892
1893
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001894 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001895 csid_hw->hw_intf->hw_idx, res->res_id);
1896
1897 init_completion(&csid_hw->csid_rdin_complete[id]);
1898
1899 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1900 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1901 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1902 val |= CSID_PATH_INFO_INPUT_EOF;
1903 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1904 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1905 } else {
1906 val &= ~(CSID_PATH_INFO_RST_DONE |
1907 CSID_PATH_ERROR_FIFO_OVERFLOW);
1908 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1909 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1910 }
1911
1912 /*Halt the RDI path */
1913 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1914 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1915
1916 return rc;
1917}
1918
1919static int cam_ife_csid_get_time_stamp(
1920 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1921{
1922 struct cam_csid_get_time_stamp_args *time_stamp;
1923 struct cam_isp_resource_node *res;
1924 struct cam_ife_csid_reg_offset *csid_reg;
1925 struct cam_hw_soc_info *soc_info;
1926 uint32_t time_32, id;
1927
1928 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1929 res = time_stamp->node_res;
1930 csid_reg = csid_hw->csid_info->csid_reg;
1931 soc_info = &csid_hw->hw_info->soc_info;
1932
1933 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1934 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001935 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1936 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001937 res->res_id);
1938 return -EINVAL;
1939 }
1940
1941 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001942 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1943 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001944 csid_hw->hw_info->hw_state);
1945 return -EINVAL;
1946 }
1947
1948 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1949 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1950 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1951 time_stamp->time_stamp_val = time_32;
1952 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1953 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1954 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1955 time_stamp->time_stamp_val |= time_32;
1956 } else {
1957 id = res->res_id;
1958 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1959 csid_reg->rdi_reg[id]->
1960 csid_rdi_timestamp_curr1_sof_addr);
1961 time_stamp->time_stamp_val = time_32;
1962 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1963
1964 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1965 csid_reg->rdi_reg[id]->
1966 csid_rdi_timestamp_curr0_sof_addr);
1967 time_stamp->time_stamp_val |= time_32;
1968 }
1969
1970 return 0;
1971}
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05301972
1973static int cam_ife_csid_set_csid_debug(struct cam_ife_csid_hw *csid_hw,
1974 void *cmd_args)
1975{
1976 uint32_t *csid_debug;
1977
1978 csid_debug = (uint32_t *) cmd_args;
1979 csid_hw->csid_debug = *csid_debug;
1980 CAM_DBG(CAM_ISP, "CSID:%d set csid debug value:%d",
1981 csid_hw->hw_intf->hw_idx, csid_hw->csid_debug);
1982
1983 return 0;
1984}
1985
Jing Zhouff57d862017-03-21 00:54:25 -07001986static int cam_ife_csid_res_wait_for_halt(
1987 struct cam_ife_csid_hw *csid_hw,
1988 struct cam_isp_resource_node *res)
1989{
1990 int rc = 0;
1991 struct cam_ife_csid_reg_offset *csid_reg;
1992 struct cam_hw_soc_info *soc_info;
1993
1994 struct completion *complete;
1995 uint32_t val = 0, id;
1996
1997 csid_reg = csid_hw->csid_info->csid_reg;
1998 soc_info = &csid_hw->hw_info->soc_info;
1999
2000 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002001 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
2002 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002003 return -EINVAL;
2004 }
2005
2006 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
2007 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002008 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
2009 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002010 res->res_id, res->res_state);
2011 return rc;
2012 }
2013
2014 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002015 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
2016 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07002017 res->res_state);
2018 return -EINVAL;
2019 }
2020
2021 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2022 complete = &csid_hw->csid_ipp_complete;
2023 else
2024 complete = &csid_hw->csid_rdin_complete[res->res_id];
2025
2026 rc = wait_for_completion_timeout(complete,
2027 msecs_to_jiffies(IFE_CSID_TIMEOUT));
2028 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002029 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
2030 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002031 res->res_id, rc);
2032 if (rc == 0)
2033 /* continue even have timeout */
2034 rc = -ETIMEDOUT;
2035 }
2036
2037 /* Disable the interrupt */
2038 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
2039 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2040 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2041 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2042 CSID_PATH_ERROR_FIFO_OVERFLOW);
2043 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2044 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
2045 } else {
2046 id = res->res_id;
2047 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2048 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2049 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
2050 CSID_PATH_ERROR_FIFO_OVERFLOW);
2051 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
2052 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
2053 }
2054 /* set state to init HW */
2055 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
2056 return rc;
2057}
2058
2059static int cam_ife_csid_get_hw_caps(void *hw_priv,
2060 void *get_hw_cap_args, uint32_t arg_size)
2061{
2062 int rc = 0;
2063 struct cam_ife_csid_hw_caps *hw_caps;
2064 struct cam_ife_csid_hw *csid_hw;
2065 struct cam_hw_info *csid_hw_info;
2066 struct cam_ife_csid_reg_offset *csid_reg;
2067
2068 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002069 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002070 return -EINVAL;
2071 }
2072
2073 csid_hw_info = (struct cam_hw_info *)hw_priv;
2074 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2075 csid_reg = csid_hw->csid_info->csid_reg;
2076 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
2077
2078 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
2079 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
2080 hw_caps->major_version = csid_reg->cmn_reg->major_version;
2081 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
2082 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
2083
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002084 CAM_DBG(CAM_ISP,
2085 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
2086 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07002087 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
2088 hw_caps->version_incr);
2089
2090 return rc;
2091}
2092
2093static int cam_ife_csid_reset(void *hw_priv,
2094 void *reset_args, uint32_t arg_size)
2095{
2096 struct cam_ife_csid_hw *csid_hw;
2097 struct cam_hw_info *csid_hw_info;
2098 struct cam_csid_reset_cfg_args *reset;
2099 int rc = 0;
2100
2101 if (!hw_priv || !reset_args || (arg_size !=
2102 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002103 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002104 return -EINVAL;
2105 }
2106
2107 csid_hw_info = (struct cam_hw_info *)hw_priv;
2108 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2109 reset = (struct cam_csid_reset_cfg_args *)reset_args;
2110
2111 switch (reset->reset_type) {
2112 case CAM_IFE_CSID_RESET_GLOBAL:
2113 rc = cam_ife_csid_global_reset(csid_hw);
2114 break;
2115 case CAM_IFE_CSID_RESET_PATH:
2116 rc = cam_ife_csid_path_reset(csid_hw, reset);
2117 break;
2118 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002119 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
2120 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002121 rc = -EINVAL;
2122 break;
2123 }
2124
2125 return rc;
2126}
2127
2128static int cam_ife_csid_reserve(void *hw_priv,
2129 void *reserve_args, uint32_t arg_size)
2130{
2131 int rc = 0;
2132 struct cam_ife_csid_hw *csid_hw;
2133 struct cam_hw_info *csid_hw_info;
2134 struct cam_csid_hw_reserve_resource_args *reserv;
2135
2136 if (!hw_priv || !reserve_args || (arg_size !=
2137 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002138 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002139 return -EINVAL;
2140 }
2141
2142 csid_hw_info = (struct cam_hw_info *)hw_priv;
2143 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2144 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2145
2146 mutex_lock(&csid_hw->hw_info->hw_mutex);
2147 switch (reserv->res_type) {
2148 case CAM_ISP_RESOURCE_CID:
2149 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2150 break;
2151 case CAM_ISP_RESOURCE_PIX_PATH:
2152 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2153 break;
2154 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002155 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2156 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002157 rc = -EINVAL;
2158 break;
2159 }
2160 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2161 return rc;
2162}
2163
2164static int cam_ife_csid_release(void *hw_priv,
2165 void *release_args, uint32_t arg_size)
2166{
2167 int rc = 0;
2168 struct cam_ife_csid_hw *csid_hw;
2169 struct cam_hw_info *csid_hw_info;
2170 struct cam_isp_resource_node *res;
2171 struct cam_ife_csid_cid_data *cid_data;
2172
2173 if (!hw_priv || !release_args ||
2174 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002175 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002176 return -EINVAL;
2177 }
2178
2179 csid_hw_info = (struct cam_hw_info *)hw_priv;
2180 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2181 res = (struct cam_isp_resource_node *)release_args;
2182
2183 mutex_lock(&csid_hw->hw_info->hw_mutex);
2184 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2185 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2186 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2187 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
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 goto end;
2193 }
2194
2195 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002196 CAM_DBG(CAM_ISP,
2197 "CSID:%d res type:%d Res %d in released state",
2198 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002199 res->res_type, res->res_id);
2200 goto end;
2201 }
2202
2203 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2204 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002205 CAM_DBG(CAM_ISP,
2206 "CSID:%d res type:%d Res id:%d invalid state:%d",
2207 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002208 res->res_type, res->res_id, res->res_state);
2209 rc = -EINVAL;
2210 goto end;
2211 }
2212
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002213 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2214 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002215
2216 switch (res->res_type) {
2217 case CAM_ISP_RESOURCE_CID:
2218 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2219 if (cid_data->cnt)
2220 cid_data->cnt--;
2221
2222 if (!cid_data->cnt)
2223 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2224
2225 if (csid_hw->csi2_reserve_cnt)
2226 csid_hw->csi2_reserve_cnt--;
2227
2228 if (!csid_hw->csi2_reserve_cnt)
2229 memset(&csid_hw->csi2_rx_cfg, 0,
2230 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2231
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002232 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2233 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002234 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2235
2236 break;
2237 case CAM_ISP_RESOURCE_PIX_PATH:
2238 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2239 break;
2240 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002241 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2242 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002243 res->res_id);
2244 rc = -EINVAL;
2245 break;
2246 }
2247
2248end:
2249 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2250 return rc;
2251}
2252
2253static int cam_ife_csid_init_hw(void *hw_priv,
2254 void *init_args, uint32_t arg_size)
2255{
2256 int rc = 0;
2257 struct cam_ife_csid_hw *csid_hw;
2258 struct cam_hw_info *csid_hw_info;
2259 struct cam_isp_resource_node *res;
2260 struct cam_ife_csid_reg_offset *csid_reg;
2261
2262 if (!hw_priv || !init_args ||
2263 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002264 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002265 return -EINVAL;
2266 }
2267
2268 csid_hw_info = (struct cam_hw_info *)hw_priv;
2269 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2270 res = (struct cam_isp_resource_node *)init_args;
2271 csid_reg = csid_hw->csid_info->csid_reg;
2272
2273 mutex_lock(&csid_hw->hw_info->hw_mutex);
2274 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2275 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2276 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2277 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002278 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2279 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002280 res->res_id);
2281 rc = -EINVAL;
2282 goto end;
2283 }
2284
2285
2286 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2287 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002288 CAM_ERR(CAM_ISP,
2289 "CSID:%d res type:%d res_id:%dInvalid state %d",
2290 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002291 res->res_type, res->res_id, res->res_state);
2292 rc = -EINVAL;
2293 goto end;
2294 }
2295
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002296 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002297 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2298
2299
2300 /* Initialize the csid hardware */
2301 rc = cam_ife_csid_enable_hw(csid_hw);
2302 if (rc)
2303 goto end;
2304
2305 switch (res->res_type) {
2306 case CAM_ISP_RESOURCE_CID:
2307 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2308 break;
2309 case CAM_ISP_RESOURCE_PIX_PATH:
2310 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2311 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2312 else
2313 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2314
2315 break;
2316 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002317 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2318 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002319 res->res_type);
2320 break;
2321 }
2322
2323 if (rc)
2324 cam_ife_csid_disable_hw(csid_hw);
2325end:
2326 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2327 return rc;
2328}
2329
2330static int cam_ife_csid_deinit_hw(void *hw_priv,
2331 void *deinit_args, uint32_t arg_size)
2332{
2333 int rc = 0;
2334 struct cam_ife_csid_hw *csid_hw;
2335 struct cam_hw_info *csid_hw_info;
2336 struct cam_isp_resource_node *res;
2337
2338 if (!hw_priv || !deinit_args ||
2339 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002340 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002341 return -EINVAL;
2342 }
2343
2344 res = (struct cam_isp_resource_node *)deinit_args;
2345 csid_hw_info = (struct cam_hw_info *)hw_priv;
2346 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2347
2348 mutex_lock(&csid_hw->hw_info->hw_mutex);
2349 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002350 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2351 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002352 res->res_id);
2353 goto end;
2354 }
2355
2356 switch (res->res_type) {
2357 case CAM_ISP_RESOURCE_CID:
2358 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2359 break;
2360 case CAM_ISP_RESOURCE_PIX_PATH:
2361 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2362 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2363 else
2364 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2365
2366 break;
2367 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002368 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2369 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002370 res->res_type);
2371 goto end;
2372 }
2373
2374 /* Disable CSID HW */
2375 cam_ife_csid_disable_hw(csid_hw);
2376
2377end:
2378 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2379 return rc;
2380}
2381
2382static int cam_ife_csid_start(void *hw_priv, void *start_args,
2383 uint32_t arg_size)
2384{
2385 int rc = 0;
2386 struct cam_ife_csid_hw *csid_hw;
2387 struct cam_hw_info *csid_hw_info;
2388 struct cam_isp_resource_node *res;
2389 struct cam_ife_csid_reg_offset *csid_reg;
2390
2391 if (!hw_priv || !start_args ||
2392 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002393 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002394 return -EINVAL;
2395 }
2396
2397 csid_hw_info = (struct cam_hw_info *)hw_priv;
2398 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2399 res = (struct cam_isp_resource_node *)start_args;
2400 csid_reg = csid_hw->csid_info->csid_reg;
2401
Jing Zhouff57d862017-03-21 00:54:25 -07002402 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2403 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2404 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2405 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002406 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2407 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002408 res->res_id);
2409 rc = -EINVAL;
2410 goto end;
2411 }
2412
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002413 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002414 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2415
2416 switch (res->res_type) {
2417 case CAM_ISP_RESOURCE_CID:
2418 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2419 rc = cam_ife_csid_tpg_start(csid_hw, res);
2420 break;
2421 case CAM_ISP_RESOURCE_PIX_PATH:
2422 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2423 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2424 else
2425 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2426 break;
2427 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002428 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2429 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002430 res->res_type);
2431 break;
2432 }
2433end:
Jing Zhouff57d862017-03-21 00:54:25 -07002434 return rc;
2435}
2436
2437static int cam_ife_csid_stop(void *hw_priv,
2438 void *stop_args, uint32_t arg_size)
2439{
2440 int rc = 0;
2441 struct cam_ife_csid_hw *csid_hw;
2442 struct cam_hw_info *csid_hw_info;
2443 struct cam_isp_resource_node *res;
2444 struct cam_csid_hw_stop_args *csid_stop;
2445 uint32_t i;
2446
2447 if (!hw_priv || !stop_args ||
2448 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002449 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002450 return -EINVAL;
2451 }
2452 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2453 csid_hw_info = (struct cam_hw_info *)hw_priv;
2454 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2455
Jing Zhouff57d862017-03-21 00:54:25 -07002456 /* Stop the resource first */
2457 for (i = 0; i < csid_stop->num_res; i++) {
2458 res = csid_stop->node_res[i];
2459 switch (res->res_type) {
2460 case CAM_ISP_RESOURCE_CID:
2461 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2462 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2463 break;
2464 case CAM_ISP_RESOURCE_PIX_PATH:
2465 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2466 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2467 res, csid_stop->stop_cmd);
2468 else
2469 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2470 res, csid_stop->stop_cmd);
2471
2472 break;
2473 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002474 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2475 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002476 res->res_type);
2477 break;
2478 }
2479 }
2480
2481 /*wait for the path to halt */
2482 for (i = 0; i < csid_stop->num_res; i++) {
2483 res = csid_stop->node_res[i];
2484 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2485 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2486 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302487 else
2488 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002489 }
2490
Jing Zhouff57d862017-03-21 00:54:25 -07002491 return rc;
2492
2493}
2494
2495static int cam_ife_csid_read(void *hw_priv,
2496 void *read_args, uint32_t arg_size)
2497{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002498 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002499
2500 return -EINVAL;
2501}
2502
2503static int cam_ife_csid_write(void *hw_priv,
2504 void *write_args, uint32_t arg_size)
2505{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002506 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002507 return -EINVAL;
2508}
2509
2510static int cam_ife_csid_process_cmd(void *hw_priv,
2511 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2512{
2513 int rc = 0;
2514 struct cam_ife_csid_hw *csid_hw;
2515 struct cam_hw_info *csid_hw_info;
2516
2517 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002518 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002519 return -EINVAL;
2520 }
2521
2522 csid_hw_info = (struct cam_hw_info *)hw_priv;
2523 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2524
Jing Zhouff57d862017-03-21 00:54:25 -07002525 switch (cmd_type) {
2526 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2527 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2528 break;
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302529 case CAM_IFE_CSID_SET_CSID_DEBUG:
2530 rc = cam_ife_csid_set_csid_debug(csid_hw, cmd_args);
2531 break;
Jing Zhouff57d862017-03-21 00:54:25 -07002532 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002533 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2534 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002535 rc = -EINVAL;
2536 break;
2537 }
Jing Zhouff57d862017-03-21 00:54:25 -07002538
2539 return rc;
2540
2541}
2542
2543irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2544{
2545 struct cam_ife_csid_hw *csid_hw;
2546 struct cam_hw_soc_info *soc_info;
2547 struct cam_ife_csid_reg_offset *csid_reg;
2548 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0,
2549 irq_status_rdi[4];
Harsh Shahf7136392017-08-29 12:42:52 -07002550 uint32_t val;
Jing Zhouff57d862017-03-21 00:54:25 -07002551
2552 csid_hw = (struct cam_ife_csid_hw *)data;
2553
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002554 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002555
2556 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002557 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002558 return IRQ_HANDLED;
2559 }
2560
2561 csid_reg = csid_hw->csid_info->csid_reg;
2562 soc_info = &csid_hw->hw_info->soc_info;
2563
2564 /* read */
2565 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2566 csid_reg->cmn_reg->csid_top_irq_status_addr);
2567
2568 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2569 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2570
2571 if (csid_reg->cmn_reg->no_pix)
2572 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2573 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2574
2575
2576 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2577 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2578 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2579
2580 /* clear */
2581 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2582 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2583 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2584 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2585 if (csid_reg->cmn_reg->no_pix)
2586 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2587 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2588
2589 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2590 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2591 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2592 }
2593 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2594 csid_reg->cmn_reg->csid_irq_cmd_addr);
2595
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002596 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2597 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Jing Zhouff57d862017-03-21 00:54:25 -07002598
2599 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002600 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002601 complete(&csid_hw->csid_top_complete);
2602 return IRQ_HANDLED;
2603 }
2604
2605
2606 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002607 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002608 complete(&csid_hw->csid_csi2_complete);
2609 }
2610
2611 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002612 pr_err_ratelimited("CSID:%d lane 0 over flow",
2613 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002614 }
2615 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002616 pr_err_ratelimited("CSID:%d lane 1 over flow",
2617 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002618 }
2619 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002620 pr_err_ratelimited("CSID:%d lane 2 over flow",
2621 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002622 }
2623 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002624 pr_err_ratelimited("CSID:%d lane 3 over flow",
2625 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002626 }
2627 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002628 pr_err_ratelimited("CSID:%d TG OVER FLOW",
2629 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002630 }
2631 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002632 pr_err_ratelimited("CSID:%d CPHY_EOT_RECEPTION",
2633 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002634 }
2635 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002636 pr_err_ratelimited("CSID:%d CPHY_SOT_RECEPTION",
2637 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002638 }
2639 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002640 pr_err_ratelimited("CSID:%d CPHY_PH_CRC",
2641 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002642 }
2643
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302644 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
2645 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
2646 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_EOT_CAPTURED",
2647 csid_hw->hw_intf->hw_idx);
2648 }
2649 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED) {
2650 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_EOT_CAPTURED",
2651 csid_hw->hw_intf->hw_idx);
2652 }
2653 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED) {
2654 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_EOT_CAPTURED",
2655 csid_hw->hw_intf->hw_idx);
2656 }
2657 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED) {
2658 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_EOT_CAPTURED",
2659 csid_hw->hw_intf->hw_idx);
2660 }
2661 }
2662
2663 if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOT_IRQ) {
2664 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED) {
2665 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL0_SOT_CAPTURED",
2666 csid_hw->hw_intf->hw_idx);
2667 }
2668 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED) {
2669 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL1_SOT_CAPTURED",
2670 csid_hw->hw_intf->hw_idx);
2671 }
2672 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED) {
2673 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL2_SOT_CAPTURED",
2674 csid_hw->hw_intf->hw_idx);
2675 }
2676 if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED) {
2677 CAM_ERR(CAM_ISP, "CSID:%d PHY_DL3_SOT_CAPTURED",
2678 csid_hw->hw_intf->hw_idx);
2679 }
2680 }
2681
2682 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE) &&
2683 (irq_status_rx & CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED)) {
2684 CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
2685 csid_hw->hw_intf->hw_idx);
2686 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2687 csid_reg->csi2_reg->
2688 csid_csi2_rx_captured_long_pkt_0_addr);
2689 CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
2690 csid_hw->hw_intf->hw_idx,
2691 (val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
2692 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2693 csid_reg->csi2_reg->
2694 csid_csi2_rx_captured_long_pkt_1_addr);
2695 CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
2696 csid_hw->hw_intf->hw_idx, val);
2697 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2698 csid_reg->csi2_reg->
2699 csid_csi2_rx_captured_long_pkt_ftr_addr);
2700 CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
2701 csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
2702 }
2703 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE) &&
2704 (irq_status_rx & CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED)) {
2705 CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
2706 csid_hw->hw_intf->hw_idx);
2707 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2708 csid_reg->csi2_reg->
2709 csid_csi2_rx_captured_short_pkt_0_addr);
2710 CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
2711 csid_hw->hw_intf->hw_idx,
2712 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2713 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2714 csid_reg->csi2_reg->
2715 csid_csi2_rx_captured_short_pkt_1_addr);
2716 CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d", val);
2717 }
2718
2719 if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE) &&
2720 (irq_status_rx & CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED)) {
2721 CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
2722 csid_hw->hw_intf->hw_idx);
2723 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2724 csid_reg->csi2_reg->
2725 csid_csi2_rx_captured_cphy_pkt_hdr_addr);
2726 CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
2727 csid_hw->hw_intf->hw_idx,
2728 (val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
2729 }
2730
Jing Zhouff57d862017-03-21 00:54:25 -07002731 /*read the IPP errors */
2732 if (csid_reg->cmn_reg->no_pix) {
2733 /* IPP reset done bit */
2734 if (irq_status_ipp &
2735 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002736 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002737 complete(&csid_hw->csid_ipp_complete);
2738 }
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302739
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302740 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
2741 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2742 CAM_ERR(CAM_ISP, "CSID:%d IPP SOF received",
2743 csid_hw->hw_intf->hw_idx);
2744
2745 if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
2746 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2747 CAM_ERR(CAM_ISP, "CSID:%d IPP EOF received",
2748 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002749
2750 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2751 complete(&csid_hw->csid_ipp_complete);
2752
2753 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002754 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002755 csid_hw->hw_intf->hw_idx);
2756 /*Stop IPP path immediately */
2757 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2758 soc_info->reg_map[0].mem_base +
2759 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2760 }
2761 }
2762
2763 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2764 if (irq_status_rdi[i] &
2765 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302766 CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002767 complete(&csid_hw->csid_rdin_complete[i]);
2768 }
2769
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302770 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
2771 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ))
2772 CAM_ERR(CAM_ISP, "CSID RDI:%d SOF received", i);
2773
2774 if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) &&
2775 (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
2776 CAM_ERR(CAM_ISP, "CSID RDI:%d EOF received", i);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302777
Jing Zhouff57d862017-03-21 00:54:25 -07002778 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2779 complete(&csid_hw->csid_rdin_complete[i]);
2780
2781 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002782 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002783 csid_hw->hw_intf->hw_idx);
2784 /*Stop RDI path immediately */
2785 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2786 soc_info->reg_map[0].mem_base +
2787 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2788 }
2789 }
2790
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002791 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002792 return IRQ_HANDLED;
2793}
2794
2795int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2796 uint32_t csid_idx)
2797{
2798 int rc = -EINVAL;
2799 uint32_t i;
2800 struct cam_ife_csid_path_cfg *path_data;
2801 struct cam_ife_csid_cid_data *cid_data;
2802 struct cam_hw_info *csid_hw_info;
2803 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2804
2805 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002806 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002807 return rc;
2808 }
2809
2810 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2811 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2812
2813 ife_csid_hw->hw_intf = csid_hw_intf;
2814 ife_csid_hw->hw_info = csid_hw_info;
2815
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002816 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002817 ife_csid_hw->hw_intf->hw_type, csid_idx);
2818
2819
2820 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2821 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2822 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2823 init_completion(&ife_csid_hw->hw_info->hw_complete);
2824
2825 init_completion(&ife_csid_hw->csid_top_complete);
2826 init_completion(&ife_csid_hw->csid_csi2_complete);
2827 init_completion(&ife_csid_hw->csid_ipp_complete);
2828 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2829 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2830
2831
2832 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2833 cam_ife_csid_irq, ife_csid_hw);
2834 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002835 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002836 goto err;
2837 }
2838
2839 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2840 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2841 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2842 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2843 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2844 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2845 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2846 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2847 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2848 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2849 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2850
2851 /*Initialize the CID resoure */
2852 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2853 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2854 ife_csid_hw->cid_res[i].res_id = i;
2855 ife_csid_hw->cid_res[i].res_state =
2856 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2857 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2858
2859 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2860 GFP_KERNEL);
2861 if (!cid_data) {
2862 rc = -ENOMEM;
2863 goto err;
2864 }
2865 ife_csid_hw->cid_res[i].res_priv = cid_data;
2866 }
2867
2868 /* Initialize the IPP resources */
2869 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2870 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2871 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2872 ife_csid_hw->ipp_res.res_state =
2873 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2874 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2875 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2876 GFP_KERNEL);
2877 if (!path_data) {
2878 rc = -ENOMEM;
2879 goto err;
2880 }
2881 ife_csid_hw->ipp_res.res_priv = path_data;
2882 }
2883
2884 /* Initialize the RDI resource */
2885 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2886 i++) {
2887 /* res type is from RDI 0 to RDI3 */
2888 ife_csid_hw->rdi_res[i].res_type =
2889 CAM_ISP_RESOURCE_PIX_PATH;
2890 ife_csid_hw->rdi_res[i].res_id = i;
2891 ife_csid_hw->rdi_res[i].res_state =
2892 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2893 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2894
2895 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2896 GFP_KERNEL);
2897 if (!path_data) {
2898 rc = -ENOMEM;
2899 goto err;
2900 }
2901 ife_csid_hw->rdi_res[i].res_priv = path_data;
2902 }
2903
Ravikishore Pampanac19ba622017-09-21 17:20:48 +05302904 ife_csid_hw->csid_debug = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07002905 return 0;
2906err:
2907 if (rc) {
2908 kfree(ife_csid_hw->ipp_res.res_priv);
2909 for (i = 0; i <
2910 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2911 kfree(ife_csid_hw->rdi_res[i].res_priv);
2912
2913 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2914 kfree(ife_csid_hw->cid_res[i].res_priv);
2915
2916 }
2917
2918 return rc;
2919}
2920
2921
2922int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2923{
2924 int rc = -EINVAL;
2925 uint32_t i;
2926
2927 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002928 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002929 return rc;
2930 }
2931
2932 /* release the privdate data memory from resources */
2933 kfree(ife_csid_hw->ipp_res.res_priv);
2934 for (i = 0; i <
2935 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2936 i++) {
2937 kfree(ife_csid_hw->rdi_res[i].res_priv);
2938 }
2939 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2940 kfree(ife_csid_hw->cid_res[i].res_priv);
2941
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302942 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07002943
2944 return 0;
2945}