blob: 9103136282a1ec33330b7dd7bd8f457bafb1c500 [file] [log] [blame]
Jing Zhouff57d862017-03-21 00:54:25 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/iopoll.h>
14#include <linux/slab.h>
15#include <uapi/media/cam_isp.h>
16#include <uapi/media/cam_defs.h>
17
18#include "cam_ife_csid_core.h"
19#include "cam_isp_hw.h"
20#include "cam_soc_util.h"
21#include "cam_io_util.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070022#include "cam_debug_util.h"
Jing Zhouff57d862017-03-21 00:54:25 -070023
24/* Timeout value in msec */
25#define IFE_CSID_TIMEOUT 1000
26
27/* TPG VC/DT values */
28#define CAM_IFE_CSID_TPG_VC_VAL 0xA
29#define CAM_IFE_CSID_TPG_DT_VAL 0x2B
30
31/* Timeout values in usec */
32#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
33#define CAM_IFE_CSID_TIMEOUT_ALL_US 1000000
34
Harsh Shahf7136392017-08-29 12:42:52 -070035#define MEASURE_EN 0
36
Jing Zhouff57d862017-03-21 00:54:25 -070037static int cam_ife_csid_is_ipp_format_supported(
Harsh Shahf7136392017-08-29 12:42:52 -070038 uint32_t in_format)
Jing Zhouff57d862017-03-21 00:54:25 -070039{
40 int rc = -EINVAL;
41
Harsh Shahf7136392017-08-29 12:42:52 -070042 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070043 case CAM_FORMAT_MIPI_RAW_6:
44 case CAM_FORMAT_MIPI_RAW_8:
45 case CAM_FORMAT_MIPI_RAW_10:
46 case CAM_FORMAT_MIPI_RAW_12:
47 case CAM_FORMAT_MIPI_RAW_14:
48 case CAM_FORMAT_MIPI_RAW_16:
49 case CAM_FORMAT_MIPI_RAW_20:
50 case CAM_FORMAT_DPCM_10_6_10:
51 case CAM_FORMAT_DPCM_10_8_10:
52 case CAM_FORMAT_DPCM_12_6_12:
53 case CAM_FORMAT_DPCM_12_8_12:
54 case CAM_FORMAT_DPCM_14_8_14:
55 case CAM_FORMAT_DPCM_14_10_14:
56 rc = 0;
57 break;
58 default:
59 break;
60 }
61 return rc;
62}
63
Harsh Shahf7136392017-08-29 12:42:52 -070064static int cam_ife_csid_get_format_rdi(
65 uint32_t in_format, uint32_t out_format,
66 uint32_t *decode_fmt, uint32_t *plain_fmt)
Jing Zhouff57d862017-03-21 00:54:25 -070067{
68 int rc = 0;
69
Harsh Shahf7136392017-08-29 12:42:52 -070070 switch (in_format) {
Jing Zhouff57d862017-03-21 00:54:25 -070071 case CAM_FORMAT_MIPI_RAW_6:
Harsh Shahf7136392017-08-29 12:42:52 -070072 switch (out_format) {
73 case CAM_FORMAT_MIPI_RAW_6:
74 *decode_fmt = 0xf;
75 break;
76 case CAM_FORMAT_PLAIN8:
77 *decode_fmt = 0x0;
78 *plain_fmt = 0x0;
79 break;
80 default:
81 rc = -EINVAL;
82 break;
83 }
Jing Zhouff57d862017-03-21 00:54:25 -070084 break;
85 case CAM_FORMAT_MIPI_RAW_8:
Harsh Shahf7136392017-08-29 12:42:52 -070086 switch (out_format) {
87 case CAM_FORMAT_MIPI_RAW_8:
88 *decode_fmt = 0xf;
89 break;
90 case CAM_FORMAT_PLAIN8:
91 *decode_fmt = 0x1;
92 *plain_fmt = 0x0;
93 break;
94 default:
95 rc = -EINVAL;
96 break;
97 }
Jing Zhouff57d862017-03-21 00:54:25 -070098 break;
99 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700100 switch (out_format) {
101 case CAM_FORMAT_MIPI_RAW_10:
102 *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)
199 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d\n",
200 in_format, out_format);
201
202 return rc;
203}
204
205static int cam_ife_csid_get_format_ipp(
206 uint32_t in_format,
207 uint32_t *decode_fmt, uint32_t *plain_fmt)
208{
209 int rc = 0;
210
211 CAM_DBG(CAM_ISP, "input format:%d",
212 in_format);
213
214 switch (in_format) {
215 case CAM_FORMAT_MIPI_RAW_6:
216 *decode_fmt = 0;
217 *plain_fmt = 0;
218 break;
219 case CAM_FORMAT_MIPI_RAW_8:
220 *decode_fmt = 0x1;
221 *plain_fmt = 0;
222 break;
223 case CAM_FORMAT_MIPI_RAW_10:
224 *decode_fmt = 0x2;
225 *plain_fmt = 0x1;
226 break;
227 case CAM_FORMAT_MIPI_RAW_12:
228 *decode_fmt = 0x3;
229 *plain_fmt = 0x1;
230 break;
231 case CAM_FORMAT_MIPI_RAW_14:
232 *decode_fmt = 0x4;
233 *plain_fmt = 0x1;
234 break;
235 case CAM_FORMAT_MIPI_RAW_16:
236 *decode_fmt = 0x5;
237 *plain_fmt = 0x1;
238 break;
239 case CAM_FORMAT_MIPI_RAW_20:
240 *decode_fmt = 0x6;
241 *plain_fmt = 0x2;
242 break;
243 case CAM_FORMAT_DPCM_10_6_10:
244 *decode_fmt = 0x7;
245 *plain_fmt = 0x1;
246 break;
247 case CAM_FORMAT_DPCM_10_8_10:
248 *decode_fmt = 0x8;
249 *plain_fmt = 0x1;
250 break;
251 case CAM_FORMAT_DPCM_12_6_12:
252 *decode_fmt = 0x9;
253 *plain_fmt = 0x1;
254 break;
255 case CAM_FORMAT_DPCM_12_8_12:
256 *decode_fmt = 0xA;
257 *plain_fmt = 0x1;
258 break;
259 case CAM_FORMAT_DPCM_14_8_14:
260 *decode_fmt = 0xB;
261 *plain_fmt = 0x1;
262 break;
263 case CAM_FORMAT_DPCM_14_10_14:
264 *decode_fmt = 0xC;
265 *plain_fmt = 0x1;
266 break;
267 default:
268 CAM_ERR(CAM_ISP, "Unsupported format %d",
269 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700270 rc = -EINVAL;
271 }
272
Harsh Shahf7136392017-08-29 12:42:52 -0700273 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
274 *decode_fmt, *plain_fmt);
275
Jing Zhouff57d862017-03-21 00:54:25 -0700276 return rc;
277}
278
279static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
280 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
281 uint32_t res_type)
282{
283 int rc = 0;
284 struct cam_ife_csid_cid_data *cid_data;
285 uint32_t i = 0, j = 0;
286
287 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
288 if (csid_hw->cid_res[i].res_state >=
289 CAM_ISP_RESOURCE_STATE_RESERVED) {
290 cid_data = (struct cam_ife_csid_cid_data *)
291 csid_hw->cid_res[i].res_priv;
292 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
293 if (cid_data->tpg_set) {
294 cid_data->cnt++;
295 *res = &csid_hw->cid_res[i];
296 break;
297 }
298 } else {
299 if (cid_data->vc == vc && cid_data->dt == dt) {
300 cid_data->cnt++;
301 *res = &csid_hw->cid_res[i];
302 break;
303 }
304 }
305 }
306 }
307
308 if (i == CAM_IFE_CSID_CID_RES_MAX) {
309 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700310 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
311 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700312 rc = -EINVAL;
313 }
314
315 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
316 if (csid_hw->cid_res[j].res_state ==
317 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
318 cid_data = (struct cam_ife_csid_cid_data *)
319 csid_hw->cid_res[j].res_priv;
320 cid_data->vc = vc;
321 cid_data->dt = dt;
322 cid_data->cnt = 1;
323 csid_hw->cid_res[j].res_state =
324 CAM_ISP_RESOURCE_STATE_RESERVED;
325 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700326 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700327 csid_hw->hw_intf->hw_idx,
328 csid_hw->cid_res[j].res_id);
329 break;
330 }
331 }
332
333 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700334 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
335 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700336 rc = -EINVAL;
337 }
338 }
339
340 return rc;
341}
342
343
344static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
345{
346 struct cam_hw_soc_info *soc_info;
347 struct cam_ife_csid_reg_offset *csid_reg;
348 int rc = 0;
349 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
350 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
351
352 soc_info = &csid_hw->hw_info->soc_info;
353 csid_reg = csid_hw->csid_info->csid_reg;
354
355 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700356 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
357 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700358 csid_hw->hw_info->hw_state);
359 return -EINVAL;
360 }
361
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700362 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700363 csid_hw->hw_intf->hw_idx);
364
365 init_completion(&csid_hw->csid_top_complete);
366
367 /* Save interrupt mask registers values*/
368 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
369 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
370
371 if (csid_reg->cmn_reg->no_pix)
372 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
373 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
374
375 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
376 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
377 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
378 }
379
380 /* Mask all interrupts */
381 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
382 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
383
384 if (csid_reg->cmn_reg->no_pix)
385 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
386 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
387
388 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
389 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
390 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
391
392 /* clear all interrupts */
393 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
394 csid_reg->cmn_reg->csid_top_irq_clear_addr);
395
396 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
397 soc_info->reg_map[0].mem_base +
398 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
399
400 if (csid_reg->cmn_reg->no_pix)
401 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
402 soc_info->reg_map[0].mem_base +
403 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
404
405 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
406 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
407 soc_info->reg_map[0].mem_base +
408 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
409
410 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
411 csid_reg->cmn_reg->csid_irq_cmd_addr);
412
413 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
414 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
415
416 /* enable the IPP and RDI format measure */
417 if (csid_reg->cmn_reg->no_pix)
418 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
419 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
420
421 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
422 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
423 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
424
425 /* perform the top CSID HW reset */
426 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
427 soc_info->reg_map[0].mem_base +
428 csid_reg->cmn_reg->csid_rst_strobes_addr);
429
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700430 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700431 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
432 msecs_to_jiffies(IFE_CSID_TIMEOUT));
433 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700434 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
435 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700436 if (rc == 0)
437 rc = -ETIMEDOUT;
438 } else {
439 rc = 0;
440 }
441
442 /*restore all interrupt masks */
443 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
444 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
445
446 if (csid_reg->cmn_reg->no_pix)
447 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
448 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
449
450 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
451 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
452 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
453
454 return rc;
455}
456
457static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
458 struct cam_csid_reset_cfg_args *reset)
459{
460 int rc = 0;
461 struct cam_hw_soc_info *soc_info;
462 struct cam_isp_resource_node *res;
463 struct cam_ife_csid_reg_offset *csid_reg;
464 uint32_t reset_strb_addr, reset_strb_val, val, id;
465 struct completion *complete;
466
467 csid_reg = csid_hw->csid_info->csid_reg;
468 soc_info = &csid_hw->hw_info->soc_info;
469 res = reset->node_res;
470
471 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700472 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
473 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700474 csid_hw->hw_info->hw_state);
475 return -EINVAL;
476 }
477
478 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700479 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
480 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700481 rc = -EINVAL;
482 goto end;
483 }
484
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700485 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700486 csid_hw->hw_intf->hw_idx, res->res_id);
487
488 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
489 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700490 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
491 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700492 res->res_id);
493 return -EINVAL;
494 }
495
496 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
497 complete = &csid_hw->csid_ipp_complete;
498
499 /* Enable path reset done interrupt */
500 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
501 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
502 val |= CSID_PATH_INFO_RST_DONE;
503 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
504 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
505
506 } else {
507 id = res->res_id;
508 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700509 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
510 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700511 res->res_id);
512 return -EINVAL;
513 }
514
515 reset_strb_addr =
516 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
517 complete =
518 &csid_hw->csid_rdin_complete[id];
519
520 /* Enable path reset done interrupt */
521 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
522 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
523 val |= CSID_PATH_INFO_RST_DONE;
524 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
525 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
526 }
527
528 init_completion(complete);
529 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
530
531 /* Enable the Test gen before reset */
532 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
533 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
534
535 /* Reset the corresponding ife csid path */
536 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
537 reset_strb_addr);
538
539 rc = wait_for_completion_timeout(complete,
540 msecs_to_jiffies(IFE_CSID_TIMEOUT));
541 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700542 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
543 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700544 res->res_id, rc);
545 if (rc == 0)
546 rc = -ETIMEDOUT;
547 }
548
549 /* Disable Test Gen after reset*/
550 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
551 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
552
553end:
554 return rc;
555
556}
557
558static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
559 struct cam_csid_hw_reserve_resource_args *cid_reserv)
560{
561 int rc = 0;
562 struct cam_ife_csid_cid_data *cid_data;
563
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700564 CAM_DBG(CAM_ISP,
565 "CSID:%d res_sel:%d Lane type:%d lane_num:%d dt:%d vc:%d",
566 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700567 cid_reserv->in_port->res_type,
568 cid_reserv->in_port->lane_type,
569 cid_reserv->in_port->lane_num,
570 cid_reserv->in_port->dt,
571 cid_reserv->in_port->vc);
572
573 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700574 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
575 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700576 cid_reserv->in_port->res_type);
577 rc = -EINVAL;
578 goto end;
579 }
580
581 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
582 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700583 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
584 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700585 cid_reserv->in_port->lane_type);
586 rc = -EINVAL;
587 goto end;
588 }
589
590 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
591 cid_reserv->in_port->lane_num > 4) &&
592 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700593 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
594 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700595 cid_reserv->in_port->lane_num);
596 rc = -EINVAL;
597 goto end;
598 }
599 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
600 cid_reserv->in_port->lane_num > 3) &&
601 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700602 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
603 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700604 cid_reserv->in_port->lane_type,
605 cid_reserv->in_port->lane_num);
606 rc = -EINVAL;
607 goto end;
608 }
609
610 /* CSID CSI2 v2.0 supports 31 vc */
611 if (cid_reserv->in_port->dt > 0x3f ||
612 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700613 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
614 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700615 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
616 rc = -EINVAL;
617 goto end;
618 }
619
620 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
621 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
622 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700623 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
624 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700625 cid_reserv->in_port->format);
626 rc = -EINVAL;
627 goto end;
628 }
629
630 if (csid_hw->csi2_reserve_cnt) {
631 /* current configure res type should match requested res type */
632 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
633 rc = -EINVAL;
634 goto end;
635 }
636
637 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
638 if (csid_hw->csi2_rx_cfg.lane_cfg !=
639 cid_reserv->in_port->lane_cfg ||
640 csid_hw->csi2_rx_cfg.lane_type !=
641 cid_reserv->in_port->lane_type ||
642 csid_hw->csi2_rx_cfg.lane_num !=
643 cid_reserv->in_port->lane_num) {
644 rc = -EINVAL;
645 goto end;
646 }
647 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700648 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700649 cid_reserv->in_port->format ||
650 csid_hw->tpg_cfg.width !=
651 cid_reserv->in_port->left_width ||
652 csid_hw->tpg_cfg.height !=
653 cid_reserv->in_port->height ||
654 csid_hw->tpg_cfg.test_pattern !=
655 cid_reserv->in_port->test_pattern) {
656 rc = -EINVAL;
657 goto end;
658 }
659 }
660 }
661
662 if (!csid_hw->csi2_reserve_cnt) {
663 csid_hw->res_type = cid_reserv->in_port->res_type;
664 /* Take the first CID resource*/
665 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
666 cid_data = (struct cam_ife_csid_cid_data *)
667 csid_hw->cid_res[0].res_priv;
668
669 csid_hw->csi2_rx_cfg.lane_cfg =
670 cid_reserv->in_port->lane_cfg;
671 csid_hw->csi2_rx_cfg.lane_type =
672 cid_reserv->in_port->lane_type;
673 csid_hw->csi2_rx_cfg.lane_num =
674 cid_reserv->in_port->lane_num;
675
676 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
677 csid_hw->csi2_rx_cfg.phy_sel = 0;
678 if (cid_reserv->in_port->format >
679 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700680 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700681 rc = -EINVAL;
682 goto end;
683 }
Harsh Shahf7136392017-08-29 12:42:52 -0700684 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700685 cid_reserv->in_port->format;
686 csid_hw->tpg_cfg.width =
687 cid_reserv->in_port->left_width;
688 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
689 csid_hw->tpg_cfg.test_pattern =
690 cid_reserv->in_port->test_pattern;
691 cid_data->tpg_set = 1;
692 } else {
693 csid_hw->csi2_rx_cfg.phy_sel =
694 (cid_reserv->in_port->res_type & 0xFF) - 1;
695 }
696
697 cid_data->vc = cid_reserv->in_port->vc;
698 cid_data->dt = cid_reserv->in_port->dt;
699 cid_data->cnt = 1;
700 cid_reserv->node_res = &csid_hw->cid_res[0];
701 csid_hw->csi2_reserve_cnt++;
702
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700703 CAM_DBG(CAM_ISP,
704 "CSID:%d CID :%d resource acquired successfully",
705 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700706 cid_reserv->node_res->res_id);
707 } else {
708 rc = cam_ife_csid_cid_get(csid_hw, &cid_reserv->node_res,
709 cid_reserv->in_port->vc, cid_reserv->in_port->dt,
710 cid_reserv->in_port->res_type);
711 /* if success then increment the reserve count */
712 if (!rc) {
713 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700714 CAM_ERR(CAM_ISP,
715 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700716 csid_hw->hw_intf->hw_idx);
717 rc = -EINVAL;
718 } else {
719 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700720 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700721 csid_hw->hw_intf->hw_idx,
722 cid_reserv->node_res->res_id);
723 }
724 }
725 }
726
727end:
728 return rc;
729}
730
731
732static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
733 struct cam_csid_hw_reserve_resource_args *reserve)
734{
735 int rc = 0;
736 struct cam_ife_csid_path_cfg *path_data;
737 struct cam_isp_resource_node *res;
738
739 /* CSID CSI2 v2.0 supports 31 vc */
740 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
741 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700742 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
743 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700744 reserve->in_port->vc, reserve->in_port->dt,
745 reserve->sync_mode);
746 rc = -EINVAL;
747 goto end;
748 }
749
750 switch (reserve->res_id) {
751 case CAM_IFE_PIX_PATH_RES_IPP:
752 if (csid_hw->ipp_res.res_state !=
753 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700754 CAM_DBG(CAM_ISP,
755 "CSID:%d IPP resource not available %d",
756 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700757 csid_hw->ipp_res.res_state);
758 rc = -EINVAL;
759 goto end;
760 }
761
762 if (cam_ife_csid_is_ipp_format_supported(
763 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700764 CAM_ERR(CAM_ISP,
765 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700766 csid_hw->hw_intf->hw_idx, reserve->res_id,
767 reserve->in_port->format);
768 rc = -EINVAL;
769 goto end;
770 }
771
772 /* assign the IPP resource */
773 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700774 CAM_DBG(CAM_ISP,
775 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700776 csid_hw->hw_intf->hw_idx, res->res_id);
777
778 break;
779 case CAM_IFE_PIX_PATH_RES_RDI_0:
780 case CAM_IFE_PIX_PATH_RES_RDI_1:
781 case CAM_IFE_PIX_PATH_RES_RDI_2:
782 case CAM_IFE_PIX_PATH_RES_RDI_3:
783 if (csid_hw->rdi_res[reserve->res_id].res_state !=
784 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700785 CAM_DBG(CAM_ISP,
786 "CSID:%d RDI:%d resource not available %d",
787 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700788 reserve->res_id,
789 csid_hw->rdi_res[reserve->res_id].res_state);
790 rc = -EINVAL;
791 goto end;
792 } else {
793 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700794 CAM_DBG(CAM_ISP,
795 "CSID:%d RDI resource:%d acquire success",
796 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700797 res->res_id);
798 }
799
800 break;
801 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700802 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700803 csid_hw->hw_intf->hw_idx, reserve->res_id);
804 rc = -EINVAL;
805 goto end;
806 }
807
808 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
809 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
810
811 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700812 path_data->in_format = reserve->in_port->format;
813 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700814 path_data->master_idx = reserve->master_idx;
815 path_data->sync_mode = reserve->sync_mode;
816 path_data->height = reserve->in_port->height;
817 path_data->start_line = reserve->in_port->line_start;
818 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
819 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
820 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
821 } else {
822 path_data->dt = reserve->in_port->dt;
823 path_data->vc = reserve->in_port->vc;
824 }
825
826 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
827 path_data->crop_enable = 1;
828 path_data->start_pixel = reserve->in_port->left_start;
829 path_data->width = reserve->in_port->left_width;
830 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
831 path_data->crop_enable = 1;
832 path_data->start_pixel = reserve->in_port->right_start;
833 path_data->width = reserve->in_port->right_width;
Harsh Shahf7136392017-08-29 12:42:52 -0700834 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700835 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700836 path_data->width = reserve->in_port->left_width;
837 path_data->start_pixel = reserve->in_port->left_start;
838 }
Jing Zhouff57d862017-03-21 00:54:25 -0700839
Harsh Shahf7136392017-08-29 12:42:52 -0700840 CAM_DBG(CAM_ISP, "Res %d width %d height %d\n", reserve->res_id,
841 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700842 reserve->node_res = res;
843
844end:
845 return rc;
846}
847
848static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
849{
850 int rc = 0;
851 struct cam_ife_csid_reg_offset *csid_reg;
852 struct cam_hw_soc_info *soc_info;
853 uint32_t i, status, val;
854
855 csid_reg = csid_hw->csid_info->csid_reg;
856 soc_info = &csid_hw->hw_info->soc_info;
857
858 /* overflow check before increment */
859 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700860 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
861 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700862 return -EINVAL;
863 }
864
865 /* Increment ref Count */
866 csid_hw->hw_info->open_count++;
867 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700868 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700869 return rc;
870 }
871
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700872 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700873 csid_hw->hw_intf->hw_idx);
874
875 rc = cam_ife_csid_enable_soc_resources(soc_info);
876 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700877 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700878 csid_hw->hw_intf->hw_idx);
879 goto err;
880 }
881
882
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700883 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700884 csid_hw->hw_intf->hw_idx);
885
886 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
887 /* Enable the top IRQ interrupt */
888 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
889 csid_reg->cmn_reg->csid_top_irq_mask_addr);
890
891 rc = cam_ife_csid_global_reset(csid_hw);
892 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700893 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
894 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700895 rc = -ETIMEDOUT;
896 goto disable_soc;
897 }
898
899 /*
900 * Reset the SW registers
901 * SW register reset also reset the mask irq, so poll the irq status
902 * to check the reset complete.
903 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700904 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700905 csid_hw->hw_intf->hw_idx);
906
907 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
908 soc_info->reg_map[0].mem_base +
909 csid_reg->cmn_reg->csid_rst_strobes_addr);
910
911 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
912 csid_reg->cmn_reg->csid_top_irq_status_addr,
913 status, (status & 0x1) == 0x1,
914 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
915 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700916 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700917 rc = -ETIMEDOUT;
918 goto disable_soc;
919 }
920
921 /* clear all interrupts */
922 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
923 csid_reg->cmn_reg->csid_top_irq_clear_addr);
924
925 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
926 soc_info->reg_map[0].mem_base +
927 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
928
929 if (csid_reg->cmn_reg->no_pix)
930 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
931 soc_info->reg_map[0].mem_base +
932 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
933
934 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
935 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
936 soc_info->reg_map[0].mem_base +
937 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
938
939 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
940 csid_reg->cmn_reg->csid_irq_cmd_addr);
941
942 /* Enable the top IRQ interrupt */
943 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
944 csid_reg->cmn_reg->csid_top_irq_mask_addr);
945
946 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
947 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700948 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -0700949 csid_hw->hw_intf->hw_idx, val);
950
951 return 0;
952
953disable_soc:
954 cam_ife_csid_disable_soc_resources(soc_info);
955 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
956err:
957 csid_hw->hw_info->open_count--;
958 return rc;
959}
960
961static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
962{
963 int rc = 0;
964 struct cam_hw_soc_info *soc_info;
965 struct cam_ife_csid_reg_offset *csid_reg;
966
967
968 /* Decrement ref Count */
969 if (csid_hw->hw_info->open_count)
970 csid_hw->hw_info->open_count--;
971 if (csid_hw->hw_info->open_count)
972 return rc;
973
974 soc_info = &csid_hw->hw_info->soc_info;
975 csid_reg = csid_hw->csid_info->csid_reg;
976
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700977 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700978 csid_hw->hw_intf->hw_idx);
979
980 /*disable the top IRQ interrupt */
981 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
982 csid_reg->cmn_reg->csid_top_irq_mask_addr);
983
984 rc = cam_ife_csid_disable_soc_resources(soc_info);
985 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700986 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
987 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700988
989 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
990 return rc;
991}
992
993
994static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
995 struct cam_isp_resource_node *res)
996{
997 uint32_t val = 0;
998 struct cam_hw_soc_info *soc_info;
999
1000 csid_hw->tpg_start_cnt++;
1001 if (csid_hw->tpg_start_cnt == 1) {
1002 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001003 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1004 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001005
1006 soc_info = &csid_hw->hw_info->soc_info;
1007 {
1008 uint32_t val;
1009 uint32_t i;
1010 uint32_t base = 0x600;
1011
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001012 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001013 for (i = 0; i < 16; i++) {
1014 val = cam_io_r_mb(
1015 soc_info->reg_map[0].mem_base +
1016 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001017 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001018 (base + i*4), val);
1019 }
1020
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001021 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001022 base = 0x200;
1023 for (i = 0; i < 10; i++) {
1024 val = cam_io_r_mb(
1025 soc_info->reg_map[0].mem_base +
1026 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001027 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001028 (base + i*4), val);
1029 }
1030
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001031 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001032 base = 0x100;
1033 for (i = 0; i < 5; i++) {
1034 val = cam_io_r_mb(
1035 soc_info->reg_map[0].mem_base +
1036 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001037 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001038 (base + i*4), val);
1039 }
1040 }
1041
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001042 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001043 val = (4 << 20);
1044 val |= (0x80 << 8);
1045 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1046 val |= 7;
1047 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1048 csid_hw->csid_info->csid_reg->tpg_reg->
1049 csid_tpg_ctrl_addr);
1050
1051 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001052 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001053 }
1054
1055 return 0;
1056}
1057
1058static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1059 struct cam_isp_resource_node *res)
1060{
1061 struct cam_hw_soc_info *soc_info;
1062
1063 if (csid_hw->tpg_start_cnt)
1064 csid_hw->tpg_start_cnt--;
1065
1066 if (csid_hw->tpg_start_cnt)
1067 return 0;
1068
1069 soc_info = &csid_hw->hw_info->soc_info;
1070
1071 /* disable the TPG */
1072 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001073 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1074 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001075
1076 /*stop the TPG */
1077 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1078 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1079 }
1080
1081 return 0;
1082}
1083
1084
1085static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1086 struct cam_isp_resource_node *res)
1087{
1088 struct cam_ife_csid_reg_offset *csid_reg;
1089 struct cam_hw_soc_info *soc_info;
1090 uint32_t val = 0;
1091
1092 csid_reg = csid_hw->csid_info->csid_reg;
1093 soc_info = &csid_hw->hw_info->soc_info;
1094
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001095 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1096 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001097
1098 /* configure one DT, infinite frames */
1099 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1100 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1101 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1102
1103 /* vertical blanking count = 0x740, horzontal blanking count = 0x740*/
1104 val = (0x740 << 12) | 0x740;
1105 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1106 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1107
1108 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1109 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1110
1111 val = csid_hw->tpg_cfg.width << 16 |
1112 csid_hw->tpg_cfg.height;
1113 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1114 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1115
1116 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1117 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1118
1119 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001120 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001121 * it is one larger than the register spec format.
1122 */
Harsh Shahf7136392017-08-29 12:42:52 -07001123 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001124 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1125 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1126
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001127 /* static frame with split color bar */
1128 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001129 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1130 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1131 /* config pix pattern */
1132 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1133 soc_info->reg_map[0].mem_base +
1134 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1135
1136 return 0;
1137}
1138
1139static int cam_ife_csid_enable_csi2(
1140 struct cam_ife_csid_hw *csid_hw,
1141 struct cam_isp_resource_node *res)
1142{
1143 int rc = 0;
1144 struct cam_ife_csid_reg_offset *csid_reg;
1145 struct cam_hw_soc_info *soc_info;
1146 struct cam_ife_csid_cid_data *cid_data;
1147 uint32_t val = 0;
1148
1149 csid_reg = csid_hw->csid_info->csid_reg;
1150 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001151 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1152 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001153
1154 /* overflow check before increment */
1155 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001156 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1157 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001158 return -EINVAL;
1159 }
1160
1161 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1162
1163 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1164 csid_hw->csi2_cfg_cnt++;
1165 if (csid_hw->csi2_cfg_cnt > 1)
1166 return rc;
1167
1168 /* rx cfg0 */
1169 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1170 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1171 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001172 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001173 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1174 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1175
1176 /* rx cfg1*/
1177 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1178 /* if VC value is more than 3 than set full width of VC */
1179 if (cid_data->vc > 3)
1180 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1181
1182 /* enable packet ecc correction */
1183 val |= 1;
1184 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1185 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1186
1187 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1188 /* Config the TPG */
1189 rc = cam_ife_csid_config_tpg(csid_hw, res);
1190 if (rc) {
1191 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1192 return rc;
1193 }
1194 }
1195
1196 /*Enable the CSI2 rx inerrupts */
1197 val = CSID_CSI2_RX_INFO_RST_DONE |
1198 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1199 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1200 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1201 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1202 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1203 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1204 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
1205 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
1206 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1207 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1208
1209 return 0;
1210}
1211
1212static int cam_ife_csid_disable_csi2(
1213 struct cam_ife_csid_hw *csid_hw,
1214 struct cam_isp_resource_node *res)
1215{
1216 struct cam_ife_csid_reg_offset *csid_reg;
1217 struct cam_hw_soc_info *soc_info;
1218
1219 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001220 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1221 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001222 return -EINVAL;
1223 }
1224
1225 csid_reg = csid_hw->csid_info->csid_reg;
1226 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001227 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1228 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001229
1230 if (csid_hw->csi2_cfg_cnt)
1231 csid_hw->csi2_cfg_cnt--;
1232
1233 if (csid_hw->csi2_cfg_cnt)
1234 return 0;
1235
1236 /*Disable the CSI2 rx inerrupts */
1237 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1238 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1239
1240 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1241
1242 return 0;
1243}
1244
1245static int cam_ife_csid_init_config_ipp_path(
1246 struct cam_ife_csid_hw *csid_hw,
1247 struct cam_isp_resource_node *res)
1248{
1249 int rc = 0;
1250 struct cam_ife_csid_path_cfg *path_data;
1251 struct cam_ife_csid_reg_offset *csid_reg;
1252 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001253 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001254
1255 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1256 csid_reg = csid_hw->csid_info->csid_reg;
1257 soc_info = &csid_hw->hw_info->soc_info;
1258
1259 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001260 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1261 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001262 res->res_id);
1263 return -EINVAL;
1264 }
1265
Harsh Shahf7136392017-08-29 12:42:52 -07001266 CAM_DBG(CAM_ISP, "Config IPP Path");
1267 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1268 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001269 if (rc)
1270 return rc;
1271
Jing Zhoubb536a82017-05-18 15:20:38 -07001272 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001273 * configure the IPP and enable the time stamp capture.
1274 * enable the HW measrurement blocks
1275 */
1276 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1277 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1278 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001279 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Jing Zhouff57d862017-03-21 00:54:25 -07001280 (path_data->crop_enable & 1 <<
1281 csid_reg->cmn_reg->crop_h_en_shift_val) |
1282 (path_data->crop_enable & 1 <<
1283 csid_reg->cmn_reg->crop_v_en_shift_val) |
1284 (1 << 1) | 1;
1285 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1286 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1287 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1288
Jing Zhoudedc4762017-06-19 17:45:36 +05301289 /* select the post irq sub sample strobe for time stamp capture */
1290 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1291 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1292
Jing Zhouff57d862017-03-21 00:54:25 -07001293 if (path_data->crop_enable) {
1294 val = ((path_data->width +
1295 path_data->start_pixel) & 0xFFFF <<
1296 csid_reg->cmn_reg->crop_shift) |
1297 (path_data->start_pixel & 0xFFFF);
1298
1299 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1300 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
1301
1302 val = ((path_data->height +
1303 path_data->start_line) & 0xFFFF <<
1304 csid_reg->cmn_reg->crop_shift) |
1305 (path_data->start_line & 0xFFFF);
1306
1307 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1308 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
1309 }
1310
1311 /* set frame drop pattern to 0 and period to 1 */
1312 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1313 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1314 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1315 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1316 /* set irq sub sample pattern to 0 and period to 1 */
1317 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1318 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1319 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1320 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1321 /* set pixel drop pattern to 0 and period to 1 */
1322 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1323 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1324 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1325 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1326 /* set line drop pattern to 0 and period to 1 */
1327 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1328 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1329 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1330 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1331
1332 /*Set master or slave IPP */
1333 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1334 /*Set halt mode as master */
1335 val = CSID_HALT_MODE_MASTER << 2;
1336 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1337 /*Set halt mode as slave and set master idx */
1338 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1339 else
1340 /* Default is internal halt mode */
1341 val = 0;
1342
1343 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1344 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1345
1346 /* Enable the IPP path */
1347 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1348 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1349 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1350 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1351 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1352
1353 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1354
1355 return rc;
1356}
1357
1358static int cam_ife_csid_deinit_ipp_path(
1359 struct cam_ife_csid_hw *csid_hw,
1360 struct cam_isp_resource_node *res)
1361{
1362 int rc = 0;
1363 struct cam_ife_csid_reg_offset *csid_reg;
1364 struct cam_hw_soc_info *soc_info;
1365 uint32_t val = 0;
1366
1367 csid_reg = csid_hw->csid_info->csid_reg;
1368 soc_info = &csid_hw->hw_info->soc_info;
1369
1370 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001371 CAM_ERR(CAM_ISP,
1372 "CSID:%d Res type %d res_id:%d in wrong state %d",
1373 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001374 res->res_type, res->res_id, res->res_state);
1375 rc = -EINVAL;
1376 }
1377
1378 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001379 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1380 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001381 res->res_id);
1382 rc = -EINVAL;
1383 }
1384
1385 /* Disable the IPP path */
1386 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1387 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1388 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1389 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1390 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1391
1392 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1393 return rc;
1394}
1395
1396static int cam_ife_csid_enable_ipp_path(
1397 struct cam_ife_csid_hw *csid_hw,
1398 struct cam_isp_resource_node *res)
1399{
1400 struct cam_ife_csid_reg_offset *csid_reg;
1401 struct cam_hw_soc_info *soc_info;
1402 struct cam_ife_csid_path_cfg *path_data;
1403 uint32_t val = 0;
1404
1405 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1406 csid_reg = csid_hw->csid_info->csid_reg;
1407 soc_info = &csid_hw->hw_info->soc_info;
1408
1409 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001410 CAM_ERR(CAM_ISP,
1411 "CSID:%d res type:%d res_id:%d Invalid state%d",
1412 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001413 res->res_type, res->res_id, res->res_state);
1414 return -EINVAL;
1415 }
1416
1417 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001418 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1419 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001420 res->res_id);
1421 return -EINVAL;
1422 }
1423
Harsh Shahf7136392017-08-29 12:42:52 -07001424 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001425
Harsh Shahf7136392017-08-29 12:42:52 -07001426 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001427 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1428 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1429 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1430 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1431 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1432 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1433 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1434 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1435 soc_info->reg_map[0].mem_base +
1436 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1437 }
1438 /* for slave mode, not need to resume for slave device */
1439
1440 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301441 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Jing Zhouff57d862017-03-21 00:54:25 -07001442 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1443 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1444
1445 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1446
1447 return 0;
1448}
1449
1450static int cam_ife_csid_disable_ipp_path(
1451 struct cam_ife_csid_hw *csid_hw,
1452 struct cam_isp_resource_node *res,
1453 enum cam_ife_csid_halt_cmd stop_cmd)
1454{
1455 int rc = 0;
1456 struct cam_ife_csid_reg_offset *csid_reg;
1457 struct cam_hw_soc_info *soc_info;
1458 struct cam_ife_csid_path_cfg *path_data;
1459 uint32_t val = 0;
1460
1461 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1462 csid_reg = csid_hw->csid_info->csid_reg;
1463 soc_info = &csid_hw->hw_info->soc_info;
1464
1465 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001466 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1467 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001468 return -EINVAL;
1469 }
1470
1471 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1472 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001473 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1474 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001475 res->res_id, res->res_state);
1476 return rc;
1477 }
1478
1479 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001480 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1481 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001482 res->res_state);
1483 return -EINVAL;
1484 }
1485
1486 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001487 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1488 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001489 return -EINVAL;
1490 }
1491
1492 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1493 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001494 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1495 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001496 return -EINVAL;
1497 }
1498
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001499 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001500 csid_hw->hw_intf->hw_idx, res->res_id);
1501
1502 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1503 /* configure Halt */
1504 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1505 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1506 val &= ~0x3;
1507 val |= stop_cmd;
1508 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1509 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1510 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1511 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1512 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1513
1514 /* For slave mode, halt command should take it from master */
1515
1516 /* Enable the EOF interrupt for resume at boundary case */
1517 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1518 init_completion(&csid_hw->csid_ipp_complete);
1519 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1520 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1521 val |= CSID_PATH_INFO_INPUT_EOF;
1522 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1523 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1524 } else {
1525 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001526 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001527 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1528 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1529 }
1530
1531 return rc;
1532}
1533
1534
1535static int cam_ife_csid_init_config_rdi_path(
1536 struct cam_ife_csid_hw *csid_hw,
1537 struct cam_isp_resource_node *res)
1538{
1539 int rc = 0;
1540 struct cam_ife_csid_path_cfg *path_data;
1541 struct cam_ife_csid_reg_offset *csid_reg;
1542 struct cam_hw_soc_info *soc_info;
1543 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1544
1545 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1546 csid_reg = csid_hw->csid_info->csid_reg;
1547 soc_info = &csid_hw->hw_info->soc_info;
1548
1549 id = res->res_id;
1550 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001551 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1552 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001553 return -EINVAL;
1554 }
1555
Harsh Shahf7136392017-08-29 12:42:52 -07001556 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1557 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001558 if (rc)
1559 return rc;
1560
Jing Zhoubb536a82017-05-18 15:20:38 -07001561 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001562 * RDI path config and enable the time stamp capture
1563 * Enable the measurement blocks
1564 */
1565 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1566 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1567 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1568 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1569 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
1570 (path_data->crop_enable & 1 <<
1571 csid_reg->cmn_reg->crop_h_en_shift_val) |
1572 (path_data->crop_enable & 1 <<
1573 csid_reg->cmn_reg->crop_v_en_shift_val) |
1574 (1 << 2) | 3;
1575
1576 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1577 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1578
Jing Zhoudedc4762017-06-19 17:45:36 +05301579 /* select the post irq sub sample strobe for time stamp capture */
1580 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1581 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1582
Jing Zhouff57d862017-03-21 00:54:25 -07001583 if (path_data->crop_enable) {
1584 val = ((path_data->width +
1585 path_data->start_pixel) & 0xFFFF <<
1586 csid_reg->cmn_reg->crop_shift) |
1587 (path_data->start_pixel & 0xFFFF);
1588
1589 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1590 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
1591
1592 val = ((path_data->height +
1593 path_data->start_line) & 0xFFFF <<
1594 csid_reg->cmn_reg->crop_shift) |
1595 (path_data->start_line & 0xFFFF);
1596
1597 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1598 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
1599 }
1600 /* set frame drop pattern to 0 and period to 1 */
1601 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1602 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1603 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1604 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1605 /* set IRQ sum sabmple */
1606 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1607 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1608 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1609 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1610
1611 /* set pixel drop pattern to 0 and period to 1 */
1612 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1613 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1614 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1615 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1616 /* set line drop pattern to 0 and period to 1 */
1617 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1618 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1619 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1620 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1621
1622 /* Configure the halt mode */
1623 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1624 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1625
1626 /* Enable the RPP path */
1627 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1628 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1629 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001630#if MEASURE_EN
1631 val |= 0x2;
1632 cam_io_w_mb(0x3, soc_info->reg_map[0].mem_base +
1633 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
1634 cam_io_w_mb(path_data->height << 16 | path_data->width,
1635 soc_info->reg_map[0].mem_base +
1636 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr);
1637 CAM_DBG(CAM_ISP, "measure_cfg1 0x%x offset 0x%x\n",
1638 path_data->height << 16 | path_data->width,
1639 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
1640
1641#endif
Jing Zhouff57d862017-03-21 00:54:25 -07001642 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1643 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1644
1645 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1646
1647 return rc;
1648}
1649
1650static int cam_ife_csid_deinit_rdi_path(
1651 struct cam_ife_csid_hw *csid_hw,
1652 struct cam_isp_resource_node *res)
1653{
1654 int rc = 0;
1655 struct cam_ife_csid_reg_offset *csid_reg;
1656 struct cam_hw_soc_info *soc_info;
1657 uint32_t val = 0, id;
1658
1659 csid_reg = csid_hw->csid_info->csid_reg;
1660 soc_info = &csid_hw->hw_info->soc_info;
1661 id = res->res_id;
1662
1663 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1664 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1665 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001666 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1667 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001668 res->res_state);
1669 return -EINVAL;
1670 }
1671
1672 /* Disable the RDI path */
1673 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1674 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1675 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1676 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1677 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1678
1679 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1680 return rc;
1681}
1682
1683static int cam_ife_csid_enable_rdi_path(
1684 struct cam_ife_csid_hw *csid_hw,
1685 struct cam_isp_resource_node *res)
1686{
1687 struct cam_ife_csid_reg_offset *csid_reg;
1688 struct cam_hw_soc_info *soc_info;
1689 uint32_t id, val;
1690
1691 csid_reg = csid_hw->csid_info->csid_reg;
1692 soc_info = &csid_hw->hw_info->soc_info;
1693 id = res->res_id;
1694
1695 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1696 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1697 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001698 CAM_ERR(CAM_ISP,
1699 "CSID:%d invalid res type:%d res_id:%d state%d",
1700 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001701 res->res_type, res->res_id, res->res_state);
1702 return -EINVAL;
1703 }
1704
1705 /*resume at frame boundary */
1706 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1707 soc_info->reg_map[0].mem_base +
1708 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1709
1710 /* Enable the required RDI interrupts */
Harsh Shahf7136392017-08-29 12:42:52 -07001711 val = CSID_PATH_INFO_RST_DONE |
1712#if MEASURE_EN
1713 CSID_PATH_INFO_INPUT_SOF |
1714#endif
1715 CSID_PATH_ERROR_FIFO_OVERFLOW;
Jing Zhouff57d862017-03-21 00:54:25 -07001716 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1717 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1718
1719 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1720
1721 return 0;
1722}
1723
1724
1725static int cam_ife_csid_disable_rdi_path(
1726 struct cam_ife_csid_hw *csid_hw,
1727 struct cam_isp_resource_node *res,
1728 enum cam_ife_csid_halt_cmd stop_cmd)
1729{
1730 int rc = 0;
1731 struct cam_ife_csid_reg_offset *csid_reg;
1732 struct cam_hw_soc_info *soc_info;
1733 uint32_t val = 0, id;
1734
1735 csid_reg = csid_hw->csid_info->csid_reg;
1736 soc_info = &csid_hw->hw_info->soc_info;
1737 id = res->res_id;
1738
1739 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1740 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001741 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1742 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001743 return -EINVAL;
1744 }
1745
1746 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1747 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001748 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1749 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001750 res->res_id, res->res_state);
1751 return rc;
1752 }
1753
1754 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001755 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1756 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001757 res->res_state);
1758 return -EINVAL;
1759 }
1760
1761 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1762 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001763 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1764 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001765 return -EINVAL;
1766 }
1767
1768
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001769 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001770 csid_hw->hw_intf->hw_idx, res->res_id);
1771
1772 init_completion(&csid_hw->csid_rdin_complete[id]);
1773
1774 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1775 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1776 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1777 val |= CSID_PATH_INFO_INPUT_EOF;
1778 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1779 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1780 } else {
1781 val &= ~(CSID_PATH_INFO_RST_DONE |
1782 CSID_PATH_ERROR_FIFO_OVERFLOW);
1783 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1784 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1785 }
1786
1787 /*Halt the RDI path */
1788 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1789 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1790
1791 return rc;
1792}
1793
1794static int cam_ife_csid_get_time_stamp(
1795 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1796{
1797 struct cam_csid_get_time_stamp_args *time_stamp;
1798 struct cam_isp_resource_node *res;
1799 struct cam_ife_csid_reg_offset *csid_reg;
1800 struct cam_hw_soc_info *soc_info;
1801 uint32_t time_32, id;
1802
1803 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1804 res = time_stamp->node_res;
1805 csid_reg = csid_hw->csid_info->csid_reg;
1806 soc_info = &csid_hw->hw_info->soc_info;
1807
1808 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1809 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001810 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1811 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001812 res->res_id);
1813 return -EINVAL;
1814 }
1815
1816 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001817 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1818 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001819 csid_hw->hw_info->hw_state);
1820 return -EINVAL;
1821 }
1822
1823 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1824 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1825 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1826 time_stamp->time_stamp_val = time_32;
1827 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1828 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1829 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1830 time_stamp->time_stamp_val |= time_32;
1831 } else {
1832 id = res->res_id;
1833 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1834 csid_reg->rdi_reg[id]->
1835 csid_rdi_timestamp_curr1_sof_addr);
1836 time_stamp->time_stamp_val = time_32;
1837 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1838
1839 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1840 csid_reg->rdi_reg[id]->
1841 csid_rdi_timestamp_curr0_sof_addr);
1842 time_stamp->time_stamp_val |= time_32;
1843 }
1844
1845 return 0;
1846}
1847static int cam_ife_csid_res_wait_for_halt(
1848 struct cam_ife_csid_hw *csid_hw,
1849 struct cam_isp_resource_node *res)
1850{
1851 int rc = 0;
1852 struct cam_ife_csid_reg_offset *csid_reg;
1853 struct cam_hw_soc_info *soc_info;
1854
1855 struct completion *complete;
1856 uint32_t val = 0, id;
1857
1858 csid_reg = csid_hw->csid_info->csid_reg;
1859 soc_info = &csid_hw->hw_info->soc_info;
1860
1861 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001862 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1863 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001864 return -EINVAL;
1865 }
1866
1867 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1868 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001869 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1870 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001871 res->res_id, res->res_state);
1872 return rc;
1873 }
1874
1875 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001876 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1877 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001878 res->res_state);
1879 return -EINVAL;
1880 }
1881
1882 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
1883 complete = &csid_hw->csid_ipp_complete;
1884 else
1885 complete = &csid_hw->csid_rdin_complete[res->res_id];
1886
1887 rc = wait_for_completion_timeout(complete,
1888 msecs_to_jiffies(IFE_CSID_TIMEOUT));
1889 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001890 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
1891 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001892 res->res_id, rc);
1893 if (rc == 0)
1894 /* continue even have timeout */
1895 rc = -ETIMEDOUT;
1896 }
1897
1898 /* Disable the interrupt */
1899 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1900 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1901 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1902 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1903 CSID_PATH_ERROR_FIFO_OVERFLOW);
1904 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1905 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1906 } else {
1907 id = res->res_id;
1908 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1909 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1910 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1911 CSID_PATH_ERROR_FIFO_OVERFLOW);
1912 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1913 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1914 }
1915 /* set state to init HW */
1916 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1917 return rc;
1918}
1919
1920static int cam_ife_csid_get_hw_caps(void *hw_priv,
1921 void *get_hw_cap_args, uint32_t arg_size)
1922{
1923 int rc = 0;
1924 struct cam_ife_csid_hw_caps *hw_caps;
1925 struct cam_ife_csid_hw *csid_hw;
1926 struct cam_hw_info *csid_hw_info;
1927 struct cam_ife_csid_reg_offset *csid_reg;
1928
1929 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001930 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07001931 return -EINVAL;
1932 }
1933
1934 csid_hw_info = (struct cam_hw_info *)hw_priv;
1935 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
1936 csid_reg = csid_hw->csid_info->csid_reg;
1937 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
1938
1939 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
1940 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
1941 hw_caps->major_version = csid_reg->cmn_reg->major_version;
1942 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
1943 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
1944
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001945 CAM_DBG(CAM_ISP,
1946 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
1947 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07001948 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
1949 hw_caps->version_incr);
1950
1951 return rc;
1952}
1953
1954static int cam_ife_csid_reset(void *hw_priv,
1955 void *reset_args, uint32_t arg_size)
1956{
1957 struct cam_ife_csid_hw *csid_hw;
1958 struct cam_hw_info *csid_hw_info;
1959 struct cam_csid_reset_cfg_args *reset;
1960 int rc = 0;
1961
1962 if (!hw_priv || !reset_args || (arg_size !=
1963 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001964 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07001965 return -EINVAL;
1966 }
1967
1968 csid_hw_info = (struct cam_hw_info *)hw_priv;
1969 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
1970 reset = (struct cam_csid_reset_cfg_args *)reset_args;
1971
1972 switch (reset->reset_type) {
1973 case CAM_IFE_CSID_RESET_GLOBAL:
1974 rc = cam_ife_csid_global_reset(csid_hw);
1975 break;
1976 case CAM_IFE_CSID_RESET_PATH:
1977 rc = cam_ife_csid_path_reset(csid_hw, reset);
1978 break;
1979 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001980 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
1981 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07001982 rc = -EINVAL;
1983 break;
1984 }
1985
1986 return rc;
1987}
1988
1989static int cam_ife_csid_reserve(void *hw_priv,
1990 void *reserve_args, uint32_t arg_size)
1991{
1992 int rc = 0;
1993 struct cam_ife_csid_hw *csid_hw;
1994 struct cam_hw_info *csid_hw_info;
1995 struct cam_csid_hw_reserve_resource_args *reserv;
1996
1997 if (!hw_priv || !reserve_args || (arg_size !=
1998 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001999 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002000 return -EINVAL;
2001 }
2002
2003 csid_hw_info = (struct cam_hw_info *)hw_priv;
2004 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2005 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2006
2007 mutex_lock(&csid_hw->hw_info->hw_mutex);
2008 switch (reserv->res_type) {
2009 case CAM_ISP_RESOURCE_CID:
2010 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2011 break;
2012 case CAM_ISP_RESOURCE_PIX_PATH:
2013 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2014 break;
2015 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002016 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2017 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002018 rc = -EINVAL;
2019 break;
2020 }
2021 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2022 return rc;
2023}
2024
2025static int cam_ife_csid_release(void *hw_priv,
2026 void *release_args, uint32_t arg_size)
2027{
2028 int rc = 0;
2029 struct cam_ife_csid_hw *csid_hw;
2030 struct cam_hw_info *csid_hw_info;
2031 struct cam_isp_resource_node *res;
2032 struct cam_ife_csid_cid_data *cid_data;
2033
2034 if (!hw_priv || !release_args ||
2035 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002036 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002037 return -EINVAL;
2038 }
2039
2040 csid_hw_info = (struct cam_hw_info *)hw_priv;
2041 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2042 res = (struct cam_isp_resource_node *)release_args;
2043
2044 mutex_lock(&csid_hw->hw_info->hw_mutex);
2045 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2046 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2047 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2048 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002049 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2050 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002051 res->res_id);
2052 rc = -EINVAL;
2053 goto end;
2054 }
2055
2056 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002057 CAM_DBG(CAM_ISP,
2058 "CSID:%d res type:%d Res %d in released state",
2059 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002060 res->res_type, res->res_id);
2061 goto end;
2062 }
2063
2064 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2065 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002066 CAM_DBG(CAM_ISP,
2067 "CSID:%d res type:%d Res id:%d invalid state:%d",
2068 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002069 res->res_type, res->res_id, res->res_state);
2070 rc = -EINVAL;
2071 goto end;
2072 }
2073
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002074 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2075 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002076
2077 switch (res->res_type) {
2078 case CAM_ISP_RESOURCE_CID:
2079 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2080 if (cid_data->cnt)
2081 cid_data->cnt--;
2082
2083 if (!cid_data->cnt)
2084 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2085
2086 if (csid_hw->csi2_reserve_cnt)
2087 csid_hw->csi2_reserve_cnt--;
2088
2089 if (!csid_hw->csi2_reserve_cnt)
2090 memset(&csid_hw->csi2_rx_cfg, 0,
2091 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2092
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002093 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2094 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002095 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2096
2097 break;
2098 case CAM_ISP_RESOURCE_PIX_PATH:
2099 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2100 break;
2101 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002102 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2103 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002104 res->res_id);
2105 rc = -EINVAL;
2106 break;
2107 }
2108
2109end:
2110 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2111 return rc;
2112}
2113
2114static int cam_ife_csid_init_hw(void *hw_priv,
2115 void *init_args, uint32_t arg_size)
2116{
2117 int rc = 0;
2118 struct cam_ife_csid_hw *csid_hw;
2119 struct cam_hw_info *csid_hw_info;
2120 struct cam_isp_resource_node *res;
2121 struct cam_ife_csid_reg_offset *csid_reg;
2122
2123 if (!hw_priv || !init_args ||
2124 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002125 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002126 return -EINVAL;
2127 }
2128
2129 csid_hw_info = (struct cam_hw_info *)hw_priv;
2130 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2131 res = (struct cam_isp_resource_node *)init_args;
2132 csid_reg = csid_hw->csid_info->csid_reg;
2133
2134 mutex_lock(&csid_hw->hw_info->hw_mutex);
2135 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2136 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2137 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2138 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002139 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2140 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002141 res->res_id);
2142 rc = -EINVAL;
2143 goto end;
2144 }
2145
2146
2147 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2148 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002149 CAM_ERR(CAM_ISP,
2150 "CSID:%d res type:%d res_id:%dInvalid state %d",
2151 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002152 res->res_type, res->res_id, res->res_state);
2153 rc = -EINVAL;
2154 goto end;
2155 }
2156
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002157 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002158 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2159
2160
2161 /* Initialize the csid hardware */
2162 rc = cam_ife_csid_enable_hw(csid_hw);
2163 if (rc)
2164 goto end;
2165
2166 switch (res->res_type) {
2167 case CAM_ISP_RESOURCE_CID:
2168 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2169 break;
2170 case CAM_ISP_RESOURCE_PIX_PATH:
2171 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2172 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2173 else
2174 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2175
2176 break;
2177 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002178 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2179 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002180 res->res_type);
2181 break;
2182 }
2183
2184 if (rc)
2185 cam_ife_csid_disable_hw(csid_hw);
2186end:
2187 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2188 return rc;
2189}
2190
2191static int cam_ife_csid_deinit_hw(void *hw_priv,
2192 void *deinit_args, uint32_t arg_size)
2193{
2194 int rc = 0;
2195 struct cam_ife_csid_hw *csid_hw;
2196 struct cam_hw_info *csid_hw_info;
2197 struct cam_isp_resource_node *res;
2198
2199 if (!hw_priv || !deinit_args ||
2200 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002201 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002202 return -EINVAL;
2203 }
2204
2205 res = (struct cam_isp_resource_node *)deinit_args;
2206 csid_hw_info = (struct cam_hw_info *)hw_priv;
2207 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2208
2209 mutex_lock(&csid_hw->hw_info->hw_mutex);
2210 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002211 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2212 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002213 res->res_id);
2214 goto end;
2215 }
2216
2217 switch (res->res_type) {
2218 case CAM_ISP_RESOURCE_CID:
2219 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2220 break;
2221 case CAM_ISP_RESOURCE_PIX_PATH:
2222 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2223 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2224 else
2225 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2226
2227 break;
2228 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002229 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2230 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002231 res->res_type);
2232 goto end;
2233 }
2234
2235 /* Disable CSID HW */
2236 cam_ife_csid_disable_hw(csid_hw);
2237
2238end:
2239 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2240 return rc;
2241}
2242
2243static int cam_ife_csid_start(void *hw_priv, void *start_args,
2244 uint32_t arg_size)
2245{
2246 int rc = 0;
2247 struct cam_ife_csid_hw *csid_hw;
2248 struct cam_hw_info *csid_hw_info;
2249 struct cam_isp_resource_node *res;
2250 struct cam_ife_csid_reg_offset *csid_reg;
2251
2252 if (!hw_priv || !start_args ||
2253 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002254 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002255 return -EINVAL;
2256 }
2257
2258 csid_hw_info = (struct cam_hw_info *)hw_priv;
2259 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2260 res = (struct cam_isp_resource_node *)start_args;
2261 csid_reg = csid_hw->csid_info->csid_reg;
2262
Jing Zhouff57d862017-03-21 00:54:25 -07002263 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2264 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2265 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2266 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002267 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2268 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002269 res->res_id);
2270 rc = -EINVAL;
2271 goto end;
2272 }
2273
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002274 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002275 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2276
2277 switch (res->res_type) {
2278 case CAM_ISP_RESOURCE_CID:
2279 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2280 rc = cam_ife_csid_tpg_start(csid_hw, res);
2281 break;
2282 case CAM_ISP_RESOURCE_PIX_PATH:
2283 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2284 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2285 else
2286 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2287 break;
2288 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002289 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2290 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002291 res->res_type);
2292 break;
2293 }
2294end:
Jing Zhouff57d862017-03-21 00:54:25 -07002295 return rc;
2296}
2297
2298static int cam_ife_csid_stop(void *hw_priv,
2299 void *stop_args, uint32_t arg_size)
2300{
2301 int rc = 0;
2302 struct cam_ife_csid_hw *csid_hw;
2303 struct cam_hw_info *csid_hw_info;
2304 struct cam_isp_resource_node *res;
2305 struct cam_csid_hw_stop_args *csid_stop;
2306 uint32_t i;
2307
2308 if (!hw_priv || !stop_args ||
2309 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002310 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002311 return -EINVAL;
2312 }
2313 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2314 csid_hw_info = (struct cam_hw_info *)hw_priv;
2315 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2316
Jing Zhouff57d862017-03-21 00:54:25 -07002317 /* Stop the resource first */
2318 for (i = 0; i < csid_stop->num_res; i++) {
2319 res = csid_stop->node_res[i];
2320 switch (res->res_type) {
2321 case CAM_ISP_RESOURCE_CID:
2322 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2323 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2324 break;
2325 case CAM_ISP_RESOURCE_PIX_PATH:
2326 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2327 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2328 res, csid_stop->stop_cmd);
2329 else
2330 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2331 res, csid_stop->stop_cmd);
2332
2333 break;
2334 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002335 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2336 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002337 res->res_type);
2338 break;
2339 }
2340 }
2341
2342 /*wait for the path to halt */
2343 for (i = 0; i < csid_stop->num_res; i++) {
2344 res = csid_stop->node_res[i];
2345 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2346 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2347 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302348 else
2349 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002350 }
2351
Jing Zhouff57d862017-03-21 00:54:25 -07002352 return rc;
2353
2354}
2355
2356static int cam_ife_csid_read(void *hw_priv,
2357 void *read_args, uint32_t arg_size)
2358{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002359 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002360
2361 return -EINVAL;
2362}
2363
2364static int cam_ife_csid_write(void *hw_priv,
2365 void *write_args, uint32_t arg_size)
2366{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002367 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002368 return -EINVAL;
2369}
2370
2371static int cam_ife_csid_process_cmd(void *hw_priv,
2372 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2373{
2374 int rc = 0;
2375 struct cam_ife_csid_hw *csid_hw;
2376 struct cam_hw_info *csid_hw_info;
2377
2378 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002379 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002380 return -EINVAL;
2381 }
2382
2383 csid_hw_info = (struct cam_hw_info *)hw_priv;
2384 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2385
Jing Zhouff57d862017-03-21 00:54:25 -07002386 switch (cmd_type) {
2387 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2388 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2389 break;
2390 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002391 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2392 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002393 rc = -EINVAL;
2394 break;
2395 }
Jing Zhouff57d862017-03-21 00:54:25 -07002396
2397 return rc;
2398
2399}
2400
2401irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2402{
2403 struct cam_ife_csid_hw *csid_hw;
2404 struct cam_hw_soc_info *soc_info;
2405 struct cam_ife_csid_reg_offset *csid_reg;
2406 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0,
2407 irq_status_rdi[4];
Harsh Shahf7136392017-08-29 12:42:52 -07002408#if MEASURE_EN
2409 uint32_t val;
2410#endif
Jing Zhouff57d862017-03-21 00:54:25 -07002411
2412 csid_hw = (struct cam_ife_csid_hw *)data;
2413
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002414 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002415
2416 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002417 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002418 return IRQ_HANDLED;
2419 }
2420
2421 csid_reg = csid_hw->csid_info->csid_reg;
2422 soc_info = &csid_hw->hw_info->soc_info;
2423
2424 /* read */
2425 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2426 csid_reg->cmn_reg->csid_top_irq_status_addr);
2427
2428 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2429 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2430
2431 if (csid_reg->cmn_reg->no_pix)
2432 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2433 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2434
2435
2436 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2437 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2438 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2439
2440 /* clear */
2441 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2442 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2443 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2444 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2445 if (csid_reg->cmn_reg->no_pix)
2446 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2447 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2448
2449 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2450 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2451 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2452 }
2453 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2454 csid_reg->cmn_reg->csid_irq_cmd_addr);
2455
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002456 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2457 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Jing Zhouff57d862017-03-21 00:54:25 -07002458
2459 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002460 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002461 complete(&csid_hw->csid_top_complete);
2462 return IRQ_HANDLED;
2463 }
2464
2465
2466 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002467 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002468 complete(&csid_hw->csid_csi2_complete);
2469 }
2470
2471 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002472 pr_err_ratelimited("CSID:%d lane 0 over flow",
2473 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002474 }
2475 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002476 pr_err_ratelimited("CSID:%d lane 1 over flow",
2477 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002478 }
2479 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002480 pr_err_ratelimited("CSID:%d lane 2 over flow",
2481 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002482 }
2483 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002484 pr_err_ratelimited("CSID:%d lane 3 over flow",
2485 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002486 }
2487 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002488 pr_err_ratelimited("CSID:%d TG OVER FLOW",
2489 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002490 }
2491 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002492 pr_err_ratelimited("CSID:%d CPHY_EOT_RECEPTION",
2493 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002494 }
2495 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002496 pr_err_ratelimited("CSID:%d CPHY_SOT_RECEPTION",
2497 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002498 }
2499 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002500 pr_err_ratelimited("CSID:%d CPHY_PH_CRC",
2501 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002502 }
2503
2504 /*read the IPP errors */
2505 if (csid_reg->cmn_reg->no_pix) {
2506 /* IPP reset done bit */
2507 if (irq_status_ipp &
2508 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002509 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002510 complete(&csid_hw->csid_ipp_complete);
2511 }
2512 if (irq_status_ipp & CSID_PATH_INFO_INPUT_SOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002513 CAM_DBG(CAM_ISP, "CSID IPP SOF received");
Jing Zhouff57d862017-03-21 00:54:25 -07002514 if (irq_status_ipp & CSID_PATH_INFO_INPUT_SOL)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002515 CAM_DBG(CAM_ISP, "CSID IPP SOL received");
Jing Zhouff57d862017-03-21 00:54:25 -07002516 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOL)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002517 CAM_DBG(CAM_ISP, "CSID IPP EOL received");
Jing Zhouff57d862017-03-21 00:54:25 -07002518 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002519 CAM_DBG(CAM_ISP, "CSID IPP EOF received");
Jing Zhouff57d862017-03-21 00:54:25 -07002520
2521 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2522 complete(&csid_hw->csid_ipp_complete);
2523
2524 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002525 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002526 csid_hw->hw_intf->hw_idx);
2527 /*Stop IPP path immediately */
2528 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2529 soc_info->reg_map[0].mem_base +
2530 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2531 }
2532 }
2533
2534 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2535 if (irq_status_rdi[i] &
2536 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002537 CAM_DBG(CAM_ISP, "CSID rdi%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002538 complete(&csid_hw->csid_rdin_complete[i]);
2539 }
2540
Harsh Shahf7136392017-08-29 12:42:52 -07002541 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002542 CAM_DBG(CAM_ISP, "CSID RDI SOF received");
Harsh Shahf7136392017-08-29 12:42:52 -07002543#if MEASURE_EN
2544 val = cam_io_r(soc_info->reg_map[0].mem_base +
2545 csid_reg->rdi_reg[i]->
2546 csid_rdi_format_measure0_addr);
2547 CAM_ERR(CAM_ISP, "measure 0x%x\n", val);
2548#endif
2549 }
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302550 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002551 CAM_DBG(CAM_ISP, "CSID RDI EOF received");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302552
Jing Zhouff57d862017-03-21 00:54:25 -07002553 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2554 complete(&csid_hw->csid_rdin_complete[i]);
2555
2556 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002557 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002558 csid_hw->hw_intf->hw_idx);
2559 /*Stop RDI path immediately */
2560 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2561 soc_info->reg_map[0].mem_base +
2562 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2563 }
2564 }
2565
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002566 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002567 return IRQ_HANDLED;
2568}
2569
2570int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2571 uint32_t csid_idx)
2572{
2573 int rc = -EINVAL;
2574 uint32_t i;
2575 struct cam_ife_csid_path_cfg *path_data;
2576 struct cam_ife_csid_cid_data *cid_data;
2577 struct cam_hw_info *csid_hw_info;
2578 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2579
2580 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002581 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002582 return rc;
2583 }
2584
2585 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2586 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2587
2588 ife_csid_hw->hw_intf = csid_hw_intf;
2589 ife_csid_hw->hw_info = csid_hw_info;
2590
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002591 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002592 ife_csid_hw->hw_intf->hw_type, csid_idx);
2593
2594
2595 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2596 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2597 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2598 init_completion(&ife_csid_hw->hw_info->hw_complete);
2599
2600 init_completion(&ife_csid_hw->csid_top_complete);
2601 init_completion(&ife_csid_hw->csid_csi2_complete);
2602 init_completion(&ife_csid_hw->csid_ipp_complete);
2603 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2604 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2605
2606
2607 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2608 cam_ife_csid_irq, ife_csid_hw);
2609 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002610 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002611 goto err;
2612 }
2613
2614 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2615 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2616 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2617 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2618 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2619 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2620 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2621 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2622 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2623 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2624 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2625
2626 /*Initialize the CID resoure */
2627 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2628 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2629 ife_csid_hw->cid_res[i].res_id = i;
2630 ife_csid_hw->cid_res[i].res_state =
2631 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2632 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2633
2634 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2635 GFP_KERNEL);
2636 if (!cid_data) {
2637 rc = -ENOMEM;
2638 goto err;
2639 }
2640 ife_csid_hw->cid_res[i].res_priv = cid_data;
2641 }
2642
2643 /* Initialize the IPP resources */
2644 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2645 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2646 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2647 ife_csid_hw->ipp_res.res_state =
2648 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2649 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2650 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2651 GFP_KERNEL);
2652 if (!path_data) {
2653 rc = -ENOMEM;
2654 goto err;
2655 }
2656 ife_csid_hw->ipp_res.res_priv = path_data;
2657 }
2658
2659 /* Initialize the RDI resource */
2660 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2661 i++) {
2662 /* res type is from RDI 0 to RDI3 */
2663 ife_csid_hw->rdi_res[i].res_type =
2664 CAM_ISP_RESOURCE_PIX_PATH;
2665 ife_csid_hw->rdi_res[i].res_id = i;
2666 ife_csid_hw->rdi_res[i].res_state =
2667 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2668 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2669
2670 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2671 GFP_KERNEL);
2672 if (!path_data) {
2673 rc = -ENOMEM;
2674 goto err;
2675 }
2676 ife_csid_hw->rdi_res[i].res_priv = path_data;
2677 }
2678
2679 return 0;
2680err:
2681 if (rc) {
2682 kfree(ife_csid_hw->ipp_res.res_priv);
2683 for (i = 0; i <
2684 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2685 kfree(ife_csid_hw->rdi_res[i].res_priv);
2686
2687 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2688 kfree(ife_csid_hw->cid_res[i].res_priv);
2689
2690 }
2691
2692 return rc;
2693}
2694
2695
2696int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2697{
2698 int rc = -EINVAL;
2699 uint32_t i;
2700
2701 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002702 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002703 return rc;
2704 }
2705
2706 /* release the privdate data memory from resources */
2707 kfree(ife_csid_hw->ipp_res.res_priv);
2708 for (i = 0; i <
2709 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2710 i++) {
2711 kfree(ife_csid_hw->rdi_res[i].res_priv);
2712 }
2713 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2714 kfree(ife_csid_hw->cid_res[i].res_priv);
2715
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302716 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07002717
2718 return 0;
2719}