blob: 7b18da940120db42c9e346fbc42e2fd9ab881999 [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:
Harsh Shahea34b602017-09-29 11:42:45 -070088 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -070089 *decode_fmt = 0xf;
90 break;
91 case CAM_FORMAT_PLAIN8:
92 *decode_fmt = 0x1;
93 *plain_fmt = 0x0;
94 break;
95 default:
96 rc = -EINVAL;
97 break;
98 }
Jing Zhouff57d862017-03-21 00:54:25 -070099 break;
100 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700101 switch (out_format) {
102 case CAM_FORMAT_MIPI_RAW_10:
Harsh Shahea34b602017-09-29 11:42:45 -0700103 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700104 *decode_fmt = 0xf;
105 break;
106 case CAM_FORMAT_PLAIN16_10:
107 *decode_fmt = 0x2;
108 *plain_fmt = 0x1;
109 break;
110 default:
111 rc = -EINVAL;
112 break;
113 }
Jing Zhouff57d862017-03-21 00:54:25 -0700114 break;
115 case CAM_FORMAT_MIPI_RAW_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700116 switch (out_format) {
117 case CAM_FORMAT_MIPI_RAW_12:
118 *decode_fmt = 0xf;
119 break;
120 case CAM_FORMAT_PLAIN16_12:
121 *decode_fmt = 0x3;
122 *plain_fmt = 0x1;
123 break;
124 default:
125 rc = -EINVAL;
126 break;
127 }
Jing Zhouff57d862017-03-21 00:54:25 -0700128 break;
129 case CAM_FORMAT_MIPI_RAW_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700130 switch (out_format) {
131 case CAM_FORMAT_MIPI_RAW_14:
132 *decode_fmt = 0xf;
133 break;
134 case CAM_FORMAT_PLAIN16_14:
135 *decode_fmt = 0x4;
136 *plain_fmt = 0x1;
137 break;
138 default:
139 rc = -EINVAL;
140 break;
141 }
Jing Zhouff57d862017-03-21 00:54:25 -0700142 break;
143 case CAM_FORMAT_MIPI_RAW_16:
Harsh Shahf7136392017-08-29 12:42:52 -0700144 switch (out_format) {
145 case CAM_FORMAT_MIPI_RAW_16:
146 *decode_fmt = 0xf;
147 break;
148 case CAM_FORMAT_PLAIN16_16:
149 *decode_fmt = 0x5;
150 *plain_fmt = 0x1;
151 break;
152 default:
153 rc = -EINVAL;
154 break;
155 }
Jing Zhouff57d862017-03-21 00:54:25 -0700156 break;
157 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahf7136392017-08-29 12:42:52 -0700158 switch (out_format) {
159 case CAM_FORMAT_MIPI_RAW_20:
160 *decode_fmt = 0xf;
161 break;
162 case CAM_FORMAT_PLAIN32_20:
163 *decode_fmt = 0x6;
164 *plain_fmt = 0x2;
165 break;
166 default:
167 rc = -EINVAL;
168 break;
169 }
Jing Zhouff57d862017-03-21 00:54:25 -0700170 break;
171 case CAM_FORMAT_DPCM_10_6_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700172 *decode_fmt = 0x7;
173 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700174 break;
175 case CAM_FORMAT_DPCM_10_8_10:
Harsh Shahf7136392017-08-29 12:42:52 -0700176 *decode_fmt = 0x8;
177 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700178 break;
179 case CAM_FORMAT_DPCM_12_6_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700180 *decode_fmt = 0x9;
181 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700182 break;
183 case CAM_FORMAT_DPCM_12_8_12:
Harsh Shahf7136392017-08-29 12:42:52 -0700184 *decode_fmt = 0xA;
185 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700186 break;
187 case CAM_FORMAT_DPCM_14_8_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700188 *decode_fmt = 0xB;
189 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700190 break;
191 case CAM_FORMAT_DPCM_14_10_14:
Harsh Shahf7136392017-08-29 12:42:52 -0700192 *decode_fmt = 0xC;
193 *plain_fmt = 0x1;
Jing Zhouff57d862017-03-21 00:54:25 -0700194 break;
195 default:
Harsh Shahf7136392017-08-29 12:42:52 -0700196 rc = -EINVAL;
197 break;
198 }
199
200 if (rc)
201 CAM_ERR(CAM_ISP, "Unsupported format pair in %d out %d\n",
202 in_format, out_format);
203
204 return rc;
205}
206
207static int cam_ife_csid_get_format_ipp(
208 uint32_t in_format,
209 uint32_t *decode_fmt, uint32_t *plain_fmt)
210{
211 int rc = 0;
212
213 CAM_DBG(CAM_ISP, "input format:%d",
214 in_format);
215
216 switch (in_format) {
217 case CAM_FORMAT_MIPI_RAW_6:
218 *decode_fmt = 0;
219 *plain_fmt = 0;
220 break;
221 case CAM_FORMAT_MIPI_RAW_8:
222 *decode_fmt = 0x1;
223 *plain_fmt = 0;
224 break;
225 case CAM_FORMAT_MIPI_RAW_10:
226 *decode_fmt = 0x2;
227 *plain_fmt = 0x1;
228 break;
229 case CAM_FORMAT_MIPI_RAW_12:
230 *decode_fmt = 0x3;
231 *plain_fmt = 0x1;
232 break;
233 case CAM_FORMAT_MIPI_RAW_14:
234 *decode_fmt = 0x4;
235 *plain_fmt = 0x1;
236 break;
237 case CAM_FORMAT_MIPI_RAW_16:
238 *decode_fmt = 0x5;
239 *plain_fmt = 0x1;
240 break;
241 case CAM_FORMAT_MIPI_RAW_20:
242 *decode_fmt = 0x6;
243 *plain_fmt = 0x2;
244 break;
245 case CAM_FORMAT_DPCM_10_6_10:
246 *decode_fmt = 0x7;
247 *plain_fmt = 0x1;
248 break;
249 case CAM_FORMAT_DPCM_10_8_10:
250 *decode_fmt = 0x8;
251 *plain_fmt = 0x1;
252 break;
253 case CAM_FORMAT_DPCM_12_6_12:
254 *decode_fmt = 0x9;
255 *plain_fmt = 0x1;
256 break;
257 case CAM_FORMAT_DPCM_12_8_12:
258 *decode_fmt = 0xA;
259 *plain_fmt = 0x1;
260 break;
261 case CAM_FORMAT_DPCM_14_8_14:
262 *decode_fmt = 0xB;
263 *plain_fmt = 0x1;
264 break;
265 case CAM_FORMAT_DPCM_14_10_14:
266 *decode_fmt = 0xC;
267 *plain_fmt = 0x1;
268 break;
269 default:
270 CAM_ERR(CAM_ISP, "Unsupported format %d",
271 in_format);
Jing Zhouff57d862017-03-21 00:54:25 -0700272 rc = -EINVAL;
273 }
274
Harsh Shahf7136392017-08-29 12:42:52 -0700275 CAM_DBG(CAM_ISP, "decode_fmt:%d plain_fmt:%d",
276 *decode_fmt, *plain_fmt);
277
Jing Zhouff57d862017-03-21 00:54:25 -0700278 return rc;
279}
280
281static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
282 struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
283 uint32_t res_type)
284{
285 int rc = 0;
286 struct cam_ife_csid_cid_data *cid_data;
287 uint32_t i = 0, j = 0;
288
289 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
290 if (csid_hw->cid_res[i].res_state >=
291 CAM_ISP_RESOURCE_STATE_RESERVED) {
292 cid_data = (struct cam_ife_csid_cid_data *)
293 csid_hw->cid_res[i].res_priv;
294 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
295 if (cid_data->tpg_set) {
296 cid_data->cnt++;
297 *res = &csid_hw->cid_res[i];
298 break;
299 }
300 } else {
301 if (cid_data->vc == vc && cid_data->dt == dt) {
302 cid_data->cnt++;
303 *res = &csid_hw->cid_res[i];
304 break;
305 }
306 }
307 }
308 }
309
310 if (i == CAM_IFE_CSID_CID_RES_MAX) {
311 if (res_type == CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700312 CAM_ERR(CAM_ISP, "CSID:%d TPG CID not available",
313 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700314 rc = -EINVAL;
315 }
316
317 for (j = 0; j < CAM_IFE_CSID_CID_RES_MAX; j++) {
318 if (csid_hw->cid_res[j].res_state ==
319 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
320 cid_data = (struct cam_ife_csid_cid_data *)
321 csid_hw->cid_res[j].res_priv;
322 cid_data->vc = vc;
323 cid_data->dt = dt;
324 cid_data->cnt = 1;
325 csid_hw->cid_res[j].res_state =
326 CAM_ISP_RESOURCE_STATE_RESERVED;
327 *res = &csid_hw->cid_res[j];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700328 CAM_DBG(CAM_ISP, "CSID:%d CID %d allocated",
Jing Zhouff57d862017-03-21 00:54:25 -0700329 csid_hw->hw_intf->hw_idx,
330 csid_hw->cid_res[j].res_id);
331 break;
332 }
333 }
334
335 if (j == CAM_IFE_CSID_CID_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700336 CAM_ERR(CAM_ISP, "CSID:%d Free cid is not available",
337 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700338 rc = -EINVAL;
339 }
340 }
341
342 return rc;
343}
344
345
346static int cam_ife_csid_global_reset(struct cam_ife_csid_hw *csid_hw)
347{
348 struct cam_hw_soc_info *soc_info;
349 struct cam_ife_csid_reg_offset *csid_reg;
350 int rc = 0;
351 uint32_t i, irq_mask_rx, irq_mask_ipp = 0,
352 irq_mask_rdi[CAM_IFE_CSID_RDI_MAX];
353
354 soc_info = &csid_hw->hw_info->soc_info;
355 csid_reg = csid_hw->csid_info->csid_reg;
356
357 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700358 CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d",
359 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700360 csid_hw->hw_info->hw_state);
361 return -EINVAL;
362 }
363
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700364 CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
Jing Zhouff57d862017-03-21 00:54:25 -0700365 csid_hw->hw_intf->hw_idx);
366
367 init_completion(&csid_hw->csid_top_complete);
368
369 /* Save interrupt mask registers values*/
370 irq_mask_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
371 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
372
373 if (csid_reg->cmn_reg->no_pix)
374 irq_mask_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
375 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
376
377 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
378 irq_mask_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
379 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
380 }
381
382 /* Mask all interrupts */
383 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
384 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
385
386 if (csid_reg->cmn_reg->no_pix)
387 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
388 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
389
390 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
391 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
392 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
393
394 /* clear all interrupts */
395 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
396 csid_reg->cmn_reg->csid_top_irq_clear_addr);
397
398 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
399 soc_info->reg_map[0].mem_base +
400 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
401
402 if (csid_reg->cmn_reg->no_pix)
403 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
404 soc_info->reg_map[0].mem_base +
405 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
406
407 for (i = 0 ; i < csid_reg->cmn_reg->no_rdis; i++)
408 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
409 soc_info->reg_map[0].mem_base +
410 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
411
412 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
413 csid_reg->cmn_reg->csid_irq_cmd_addr);
414
415 cam_io_w_mb(0x80, soc_info->reg_map[0].mem_base +
416 csid_hw->csid_info->csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
417
418 /* enable the IPP and RDI format measure */
419 if (csid_reg->cmn_reg->no_pix)
420 cam_io_w_mb(0x1, soc_info->reg_map[0].mem_base +
421 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
422
423 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
424 cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
425 csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
426
427 /* perform the top CSID HW reset */
428 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
429 soc_info->reg_map[0].mem_base +
430 csid_reg->cmn_reg->csid_rst_strobes_addr);
431
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700432 CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
Jing Zhouff57d862017-03-21 00:54:25 -0700433 rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
434 msecs_to_jiffies(IFE_CSID_TIMEOUT));
435 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700436 CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
437 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700438 if (rc == 0)
439 rc = -ETIMEDOUT;
440 } else {
441 rc = 0;
442 }
443
444 /*restore all interrupt masks */
445 cam_io_w_mb(irq_mask_rx, soc_info->reg_map[0].mem_base +
446 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
447
448 if (csid_reg->cmn_reg->no_pix)
449 cam_io_w_mb(irq_mask_ipp, soc_info->reg_map[0].mem_base +
450 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
451
452 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
453 cam_io_w_mb(irq_mask_rdi[i], soc_info->reg_map[0].mem_base +
454 csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
455
456 return rc;
457}
458
459static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
460 struct cam_csid_reset_cfg_args *reset)
461{
462 int rc = 0;
463 struct cam_hw_soc_info *soc_info;
464 struct cam_isp_resource_node *res;
465 struct cam_ife_csid_reg_offset *csid_reg;
466 uint32_t reset_strb_addr, reset_strb_val, val, id;
467 struct completion *complete;
468
469 csid_reg = csid_hw->csid_info->csid_reg;
470 soc_info = &csid_hw->hw_info->soc_info;
471 res = reset->node_res;
472
473 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700474 CAM_ERR(CAM_ISP, "CSID:%d Invalid hw state :%d",
475 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700476 csid_hw->hw_info->hw_state);
477 return -EINVAL;
478 }
479
480 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700481 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
482 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -0700483 rc = -EINVAL;
484 goto end;
485 }
486
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700487 CAM_DBG(CAM_ISP, "CSID:%d resource:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700488 csid_hw->hw_intf->hw_idx, res->res_id);
489
490 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
491 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700492 CAM_ERR(CAM_ISP, "CSID:%d IPP not supported :%d",
493 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700494 res->res_id);
495 return -EINVAL;
496 }
497
498 reset_strb_addr = csid_reg->ipp_reg->csid_ipp_rst_strobes_addr;
499 complete = &csid_hw->csid_ipp_complete;
500
501 /* Enable path reset done interrupt */
502 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
503 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
504 val |= CSID_PATH_INFO_RST_DONE;
505 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
506 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
507
508 } else {
509 id = res->res_id;
510 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700511 CAM_ERR(CAM_ISP, "CSID:%d RDI res not supported :%d",
512 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700513 res->res_id);
514 return -EINVAL;
515 }
516
517 reset_strb_addr =
518 csid_reg->rdi_reg[id]->csid_rdi_rst_strobes_addr;
519 complete =
520 &csid_hw->csid_rdin_complete[id];
521
522 /* Enable path reset done interrupt */
523 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
524 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
525 val |= CSID_PATH_INFO_RST_DONE;
526 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
527 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
528 }
529
530 init_completion(complete);
531 reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
532
533 /* Enable the Test gen before reset */
534 cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
535 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
536
537 /* Reset the corresponding ife csid path */
538 cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
539 reset_strb_addr);
540
541 rc = wait_for_completion_timeout(complete,
542 msecs_to_jiffies(IFE_CSID_TIMEOUT));
543 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700544 CAM_ERR(CAM_ISP, "CSID:%d Res id %d fail rc = %d",
545 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700546 res->res_id, rc);
547 if (rc == 0)
548 rc = -ETIMEDOUT;
549 }
550
551 /* Disable Test Gen after reset*/
552 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
553 csid_reg->tpg_reg->csid_tpg_ctrl_addr);
554
555end:
556 return rc;
557
558}
559
560static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
561 struct cam_csid_hw_reserve_resource_args *cid_reserv)
562{
563 int rc = 0;
564 struct cam_ife_csid_cid_data *cid_data;
565
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700566 CAM_DBG(CAM_ISP,
567 "CSID:%d res_sel:%d Lane type:%d lane_num:%d dt:%d vc:%d",
568 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700569 cid_reserv->in_port->res_type,
570 cid_reserv->in_port->lane_type,
571 cid_reserv->in_port->lane_num,
572 cid_reserv->in_port->dt,
573 cid_reserv->in_port->vc);
574
575 if (cid_reserv->in_port->res_type >= CAM_ISP_IFE_IN_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700576 CAM_ERR(CAM_ISP, "CSID:%d Invalid phy sel %d",
577 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700578 cid_reserv->in_port->res_type);
579 rc = -EINVAL;
580 goto end;
581 }
582
583 if (cid_reserv->in_port->lane_type >= CAM_ISP_LANE_TYPE_MAX &&
584 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700585 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane type %d",
586 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700587 cid_reserv->in_port->lane_type);
588 rc = -EINVAL;
589 goto end;
590 }
591
592 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_DPHY &&
593 cid_reserv->in_port->lane_num > 4) &&
594 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700595 CAM_ERR(CAM_ISP, "CSID:%d Invalid lane num %d",
596 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700597 cid_reserv->in_port->lane_num);
598 rc = -EINVAL;
599 goto end;
600 }
601 if ((cid_reserv->in_port->lane_type == CAM_ISP_LANE_TYPE_CPHY &&
602 cid_reserv->in_port->lane_num > 3) &&
603 cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700604 CAM_ERR(CAM_ISP, " CSID:%d Invalid lane type %d & num %d",
605 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700606 cid_reserv->in_port->lane_type,
607 cid_reserv->in_port->lane_num);
608 rc = -EINVAL;
609 goto end;
610 }
611
612 /* CSID CSI2 v2.0 supports 31 vc */
613 if (cid_reserv->in_port->dt > 0x3f ||
614 cid_reserv->in_port->vc > 0x1f) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700615 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d",
616 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700617 cid_reserv->in_port->vc, cid_reserv->in_port->dt);
618 rc = -EINVAL;
619 goto end;
620 }
621
622 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG && (
623 (cid_reserv->in_port->format < CAM_FORMAT_MIPI_RAW_8 &&
624 cid_reserv->in_port->format > CAM_FORMAT_MIPI_RAW_16))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700625 CAM_ERR(CAM_ISP, " CSID:%d Invalid tpg decode fmt %d",
626 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700627 cid_reserv->in_port->format);
628 rc = -EINVAL;
629 goto end;
630 }
631
632 if (csid_hw->csi2_reserve_cnt) {
633 /* current configure res type should match requested res type */
634 if (csid_hw->res_type != cid_reserv->in_port->res_type) {
635 rc = -EINVAL;
636 goto end;
637 }
638
639 if (cid_reserv->in_port->res_type != CAM_ISP_IFE_IN_RES_TPG) {
640 if (csid_hw->csi2_rx_cfg.lane_cfg !=
641 cid_reserv->in_port->lane_cfg ||
642 csid_hw->csi2_rx_cfg.lane_type !=
643 cid_reserv->in_port->lane_type ||
644 csid_hw->csi2_rx_cfg.lane_num !=
645 cid_reserv->in_port->lane_num) {
646 rc = -EINVAL;
647 goto end;
648 }
649 } else {
Harsh Shahf7136392017-08-29 12:42:52 -0700650 if (csid_hw->tpg_cfg.in_format !=
Jing Zhouff57d862017-03-21 00:54:25 -0700651 cid_reserv->in_port->format ||
652 csid_hw->tpg_cfg.width !=
653 cid_reserv->in_port->left_width ||
654 csid_hw->tpg_cfg.height !=
655 cid_reserv->in_port->height ||
656 csid_hw->tpg_cfg.test_pattern !=
657 cid_reserv->in_port->test_pattern) {
658 rc = -EINVAL;
659 goto end;
660 }
661 }
662 }
663
664 if (!csid_hw->csi2_reserve_cnt) {
665 csid_hw->res_type = cid_reserv->in_port->res_type;
666 /* Take the first CID resource*/
667 csid_hw->cid_res[0].res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
668 cid_data = (struct cam_ife_csid_cid_data *)
669 csid_hw->cid_res[0].res_priv;
670
671 csid_hw->csi2_rx_cfg.lane_cfg =
672 cid_reserv->in_port->lane_cfg;
673 csid_hw->csi2_rx_cfg.lane_type =
674 cid_reserv->in_port->lane_type;
675 csid_hw->csi2_rx_cfg.lane_num =
676 cid_reserv->in_port->lane_num;
677
678 if (cid_reserv->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
679 csid_hw->csi2_rx_cfg.phy_sel = 0;
680 if (cid_reserv->in_port->format >
681 CAM_FORMAT_MIPI_RAW_16) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700682 CAM_ERR(CAM_ISP, " Wrong TPG format");
Jing Zhouff57d862017-03-21 00:54:25 -0700683 rc = -EINVAL;
684 goto end;
685 }
Harsh Shahf7136392017-08-29 12:42:52 -0700686 csid_hw->tpg_cfg.in_format =
Jing Zhouff57d862017-03-21 00:54:25 -0700687 cid_reserv->in_port->format;
688 csid_hw->tpg_cfg.width =
689 cid_reserv->in_port->left_width;
690 csid_hw->tpg_cfg.height = cid_reserv->in_port->height;
691 csid_hw->tpg_cfg.test_pattern =
692 cid_reserv->in_port->test_pattern;
693 cid_data->tpg_set = 1;
694 } else {
695 csid_hw->csi2_rx_cfg.phy_sel =
696 (cid_reserv->in_port->res_type & 0xFF) - 1;
697 }
698
699 cid_data->vc = cid_reserv->in_port->vc;
700 cid_data->dt = cid_reserv->in_port->dt;
701 cid_data->cnt = 1;
702 cid_reserv->node_res = &csid_hw->cid_res[0];
703 csid_hw->csi2_reserve_cnt++;
704
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700705 CAM_DBG(CAM_ISP,
706 "CSID:%d CID :%d resource acquired successfully",
707 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700708 cid_reserv->node_res->res_id);
709 } else {
710 rc = cam_ife_csid_cid_get(csid_hw, &cid_reserv->node_res,
711 cid_reserv->in_port->vc, cid_reserv->in_port->dt,
712 cid_reserv->in_port->res_type);
713 /* if success then increment the reserve count */
714 if (!rc) {
715 if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700716 CAM_ERR(CAM_ISP,
717 "CSID%d reserve cnt reached max",
Jing Zhouff57d862017-03-21 00:54:25 -0700718 csid_hw->hw_intf->hw_idx);
719 rc = -EINVAL;
720 } else {
721 csid_hw->csi2_reserve_cnt++;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700722 CAM_DBG(CAM_ISP, "CSID:%d CID:%d acquired",
Jing Zhouff57d862017-03-21 00:54:25 -0700723 csid_hw->hw_intf->hw_idx,
724 cid_reserv->node_res->res_id);
725 }
726 }
727 }
728
729end:
730 return rc;
731}
732
733
734static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
735 struct cam_csid_hw_reserve_resource_args *reserve)
736{
737 int rc = 0;
738 struct cam_ife_csid_path_cfg *path_data;
739 struct cam_isp_resource_node *res;
740
741 /* CSID CSI2 v2.0 supports 31 vc */
742 if (reserve->in_port->dt > 0x3f || reserve->in_port->vc > 0x1f ||
743 (reserve->sync_mode >= CAM_ISP_HW_SYNC_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700744 CAM_ERR(CAM_ISP, "CSID:%d Invalid vc:%d dt %d mode:%d",
745 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700746 reserve->in_port->vc, reserve->in_port->dt,
747 reserve->sync_mode);
748 rc = -EINVAL;
749 goto end;
750 }
751
752 switch (reserve->res_id) {
753 case CAM_IFE_PIX_PATH_RES_IPP:
754 if (csid_hw->ipp_res.res_state !=
755 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700756 CAM_DBG(CAM_ISP,
757 "CSID:%d IPP resource not available %d",
758 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700759 csid_hw->ipp_res.res_state);
760 rc = -EINVAL;
761 goto end;
762 }
763
764 if (cam_ife_csid_is_ipp_format_supported(
765 reserve->in_port->format)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700766 CAM_ERR(CAM_ISP,
767 "CSID:%d res id:%d un support format %d",
Jing Zhouff57d862017-03-21 00:54:25 -0700768 csid_hw->hw_intf->hw_idx, reserve->res_id,
769 reserve->in_port->format);
770 rc = -EINVAL;
771 goto end;
772 }
773
774 /* assign the IPP resource */
775 res = &csid_hw->ipp_res;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700776 CAM_DBG(CAM_ISP,
777 "CSID:%d IPP resource:%d acquired successfully",
Jing Zhouff57d862017-03-21 00:54:25 -0700778 csid_hw->hw_intf->hw_idx, res->res_id);
779
780 break;
781 case CAM_IFE_PIX_PATH_RES_RDI_0:
782 case CAM_IFE_PIX_PATH_RES_RDI_1:
783 case CAM_IFE_PIX_PATH_RES_RDI_2:
784 case CAM_IFE_PIX_PATH_RES_RDI_3:
785 if (csid_hw->rdi_res[reserve->res_id].res_state !=
786 CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700787 CAM_DBG(CAM_ISP,
788 "CSID:%d RDI:%d resource not available %d",
789 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700790 reserve->res_id,
791 csid_hw->rdi_res[reserve->res_id].res_state);
792 rc = -EINVAL;
793 goto end;
794 } else {
795 res = &csid_hw->rdi_res[reserve->res_id];
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700796 CAM_DBG(CAM_ISP,
797 "CSID:%d RDI resource:%d acquire success",
798 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -0700799 res->res_id);
800 }
801
802 break;
803 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700804 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -0700805 csid_hw->hw_intf->hw_idx, reserve->res_id);
806 rc = -EINVAL;
807 goto end;
808 }
809
810 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
811 path_data = (struct cam_ife_csid_path_cfg *)res->res_priv;
812
813 path_data->cid = reserve->cid;
Harsh Shahf7136392017-08-29 12:42:52 -0700814 path_data->in_format = reserve->in_port->format;
815 path_data->out_format = reserve->out_port->format;
Jing Zhouff57d862017-03-21 00:54:25 -0700816 path_data->master_idx = reserve->master_idx;
817 path_data->sync_mode = reserve->sync_mode;
818 path_data->height = reserve->in_port->height;
819 path_data->start_line = reserve->in_port->line_start;
820 if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
821 path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
822 path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
823 } else {
824 path_data->dt = reserve->in_port->dt;
825 path_data->vc = reserve->in_port->vc;
826 }
827
828 if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
829 path_data->crop_enable = 1;
830 path_data->start_pixel = reserve->in_port->left_start;
831 path_data->width = reserve->in_port->left_width;
832 } else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
833 path_data->crop_enable = 1;
834 path_data->start_pixel = reserve->in_port->right_start;
835 path_data->width = reserve->in_port->right_width;
Harsh Shahf7136392017-08-29 12:42:52 -0700836 } else {
Jing Zhouff57d862017-03-21 00:54:25 -0700837 path_data->crop_enable = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700838 path_data->width = reserve->in_port->left_width;
839 path_data->start_pixel = reserve->in_port->left_start;
840 }
Jing Zhouff57d862017-03-21 00:54:25 -0700841
Harsh Shahf7136392017-08-29 12:42:52 -0700842 CAM_DBG(CAM_ISP, "Res %d width %d height %d\n", reserve->res_id,
843 path_data->width, path_data->height);
Jing Zhouff57d862017-03-21 00:54:25 -0700844 reserve->node_res = res;
845
846end:
847 return rc;
848}
849
850static int cam_ife_csid_enable_hw(struct cam_ife_csid_hw *csid_hw)
851{
852 int rc = 0;
853 struct cam_ife_csid_reg_offset *csid_reg;
854 struct cam_hw_soc_info *soc_info;
855 uint32_t i, status, val;
856
857 csid_reg = csid_hw->csid_info->csid_reg;
858 soc_info = &csid_hw->hw_info->soc_info;
859
860 /* overflow check before increment */
861 if (csid_hw->hw_info->open_count == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700862 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
863 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700864 return -EINVAL;
865 }
866
867 /* Increment ref Count */
868 csid_hw->hw_info->open_count++;
869 if (csid_hw->hw_info->open_count > 1) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700870 CAM_DBG(CAM_ISP, "CSID hw has already been enabled");
Jing Zhouff57d862017-03-21 00:54:25 -0700871 return rc;
872 }
873
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700874 CAM_DBG(CAM_ISP, "CSID:%d init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700875 csid_hw->hw_intf->hw_idx);
876
877 rc = cam_ife_csid_enable_soc_resources(soc_info);
878 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700879 CAM_ERR(CAM_ISP, "CSID:%d Enable SOC failed",
Jing Zhouff57d862017-03-21 00:54:25 -0700880 csid_hw->hw_intf->hw_idx);
881 goto err;
882 }
883
884
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700885 CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
Jing Zhouff57d862017-03-21 00:54:25 -0700886 csid_hw->hw_intf->hw_idx);
887
888 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
889 /* Enable the top IRQ interrupt */
890 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
891 csid_reg->cmn_reg->csid_top_irq_mask_addr);
892
893 rc = cam_ife_csid_global_reset(csid_hw);
894 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700895 CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
896 csid_hw->hw_intf->hw_idx, rc);
Jing Zhouff57d862017-03-21 00:54:25 -0700897 rc = -ETIMEDOUT;
898 goto disable_soc;
899 }
900
901 /*
902 * Reset the SW registers
903 * SW register reset also reset the mask irq, so poll the irq status
904 * to check the reset complete.
905 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700906 CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
Jing Zhouff57d862017-03-21 00:54:25 -0700907 csid_hw->hw_intf->hw_idx);
908
909 cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
910 soc_info->reg_map[0].mem_base +
911 csid_reg->cmn_reg->csid_rst_strobes_addr);
912
913 rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
914 csid_reg->cmn_reg->csid_top_irq_status_addr,
915 status, (status & 0x1) == 0x1,
916 CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
917 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700918 CAM_ERR(CAM_ISP, "software register reset timeout.....");
Jing Zhouff57d862017-03-21 00:54:25 -0700919 rc = -ETIMEDOUT;
920 goto disable_soc;
921 }
922
923 /* clear all interrupts */
924 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
925 csid_reg->cmn_reg->csid_top_irq_clear_addr);
926
927 cam_io_w_mb(csid_reg->csi2_reg->csi2_irq_mask_all,
928 soc_info->reg_map[0].mem_base +
929 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
930
931 if (csid_reg->cmn_reg->no_pix)
932 cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
933 soc_info->reg_map[0].mem_base +
934 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
935
936 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
937 cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
938 soc_info->reg_map[0].mem_base +
939 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
940
941 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
942 csid_reg->cmn_reg->csid_irq_cmd_addr);
943
944 /* Enable the top IRQ interrupt */
945 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
946 csid_reg->cmn_reg->csid_top_irq_mask_addr);
947
948 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
949 csid_reg->cmn_reg->csid_hw_version_addr);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700950 CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -0700951 csid_hw->hw_intf->hw_idx, val);
952
953 return 0;
954
955disable_soc:
956 cam_ife_csid_disable_soc_resources(soc_info);
957 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
958err:
959 csid_hw->hw_info->open_count--;
960 return rc;
961}
962
963static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
964{
965 int rc = 0;
966 struct cam_hw_soc_info *soc_info;
967 struct cam_ife_csid_reg_offset *csid_reg;
968
969
970 /* Decrement ref Count */
971 if (csid_hw->hw_info->open_count)
972 csid_hw->hw_info->open_count--;
973 if (csid_hw->hw_info->open_count)
974 return rc;
975
976 soc_info = &csid_hw->hw_info->soc_info;
977 csid_reg = csid_hw->csid_info->csid_reg;
978
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700979 CAM_DBG(CAM_ISP, "CSID:%d De-init CSID HW",
Jing Zhouff57d862017-03-21 00:54:25 -0700980 csid_hw->hw_intf->hw_idx);
981
982 /*disable the top IRQ interrupt */
983 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
984 csid_reg->cmn_reg->csid_top_irq_mask_addr);
985
986 rc = cam_ife_csid_disable_soc_resources(soc_info);
987 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700988 CAM_ERR(CAM_ISP, "CSID:%d Disable CSID SOC failed",
989 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -0700990
991 csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
992 return rc;
993}
994
995
996static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
997 struct cam_isp_resource_node *res)
998{
999 uint32_t val = 0;
1000 struct cam_hw_soc_info *soc_info;
1001
1002 csid_hw->tpg_start_cnt++;
1003 if (csid_hw->tpg_start_cnt == 1) {
1004 /*Enable the TPG */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001005 CAM_DBG(CAM_ISP, "CSID:%d start CSID TPG",
1006 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001007
1008 soc_info = &csid_hw->hw_info->soc_info;
1009 {
1010 uint32_t val;
1011 uint32_t i;
1012 uint32_t base = 0x600;
1013
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001014 CAM_DBG(CAM_ISP, "================ TPG ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001015 for (i = 0; i < 16; i++) {
1016 val = cam_io_r_mb(
1017 soc_info->reg_map[0].mem_base +
1018 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001019 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001020 (base + i*4), val);
1021 }
1022
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001023 CAM_DBG(CAM_ISP, "================ IPP =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001024 base = 0x200;
1025 for (i = 0; i < 10; i++) {
1026 val = cam_io_r_mb(
1027 soc_info->reg_map[0].mem_base +
1028 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001029 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001030 (base + i*4), val);
1031 }
1032
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001033 CAM_DBG(CAM_ISP, "================ RX =============");
Jing Zhouff57d862017-03-21 00:54:25 -07001034 base = 0x100;
1035 for (i = 0; i < 5; i++) {
1036 val = cam_io_r_mb(
1037 soc_info->reg_map[0].mem_base +
1038 base + i * 4);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001039 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x",
Jing Zhouff57d862017-03-21 00:54:25 -07001040 (base + i*4), val);
1041 }
1042 }
1043
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001044 CAM_DBG(CAM_ISP, "============ TPG control ============");
Jing Zhouff57d862017-03-21 00:54:25 -07001045 val = (4 << 20);
1046 val |= (0x80 << 8);
1047 val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
1048 val |= 7;
1049 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1050 csid_hw->csid_info->csid_reg->tpg_reg->
1051 csid_tpg_ctrl_addr);
1052
1053 val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001054 CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
Jing Zhouff57d862017-03-21 00:54:25 -07001055 }
1056
1057 return 0;
1058}
1059
1060static int cam_ife_csid_tpg_stop(struct cam_ife_csid_hw *csid_hw,
1061 struct cam_isp_resource_node *res)
1062{
1063 struct cam_hw_soc_info *soc_info;
1064
1065 if (csid_hw->tpg_start_cnt)
1066 csid_hw->tpg_start_cnt--;
1067
1068 if (csid_hw->tpg_start_cnt)
1069 return 0;
1070
1071 soc_info = &csid_hw->hw_info->soc_info;
1072
1073 /* disable the TPG */
1074 if (!csid_hw->tpg_start_cnt) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001075 CAM_DBG(CAM_ISP, "CSID:%d stop CSID TPG",
1076 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001077
1078 /*stop the TPG */
1079 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1080 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_ctrl_addr);
1081 }
1082
1083 return 0;
1084}
1085
1086
1087static int cam_ife_csid_config_tpg(struct cam_ife_csid_hw *csid_hw,
1088 struct cam_isp_resource_node *res)
1089{
1090 struct cam_ife_csid_reg_offset *csid_reg;
1091 struct cam_hw_soc_info *soc_info;
1092 uint32_t val = 0;
1093
1094 csid_reg = csid_hw->csid_info->csid_reg;
1095 soc_info = &csid_hw->hw_info->soc_info;
1096
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001097 CAM_DBG(CAM_ISP, "CSID:%d TPG config",
1098 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001099
1100 /* configure one DT, infinite frames */
1101 val = (0 << 16) | (1 << 10) | CAM_IFE_CSID_TPG_VC_VAL;
1102 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1103 csid_reg->tpg_reg->csid_tpg_vc_cfg0_addr);
1104
1105 /* vertical blanking count = 0x740, horzontal blanking count = 0x740*/
1106 val = (0x740 << 12) | 0x740;
1107 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1108 csid_reg->tpg_reg->csid_tpg_vc_cfg1_addr);
1109
1110 cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
1111 csid_hw->csid_info->csid_reg->tpg_reg->csid_tpg_lfsr_seed_addr);
1112
1113 val = csid_hw->tpg_cfg.width << 16 |
1114 csid_hw->tpg_cfg.height;
1115 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1116 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_0_addr);
1117
1118 cam_io_w_mb(CAM_IFE_CSID_TPG_DT_VAL, soc_info->reg_map[0].mem_base +
1119 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_1_addr);
1120
1121 /*
Harsh Shahf7136392017-08-29 12:42:52 -07001122 * in_format is the same as the input resource format.
Jing Zhouff57d862017-03-21 00:54:25 -07001123 * it is one larger than the register spec format.
1124 */
Harsh Shahf7136392017-08-29 12:42:52 -07001125 val = ((csid_hw->tpg_cfg.in_format - 1) << 16) | 0x8;
Jing Zhouff57d862017-03-21 00:54:25 -07001126 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1127 csid_reg->tpg_reg->csid_tpg_dt_n_cfg_2_addr);
1128
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001129 /* static frame with split color bar */
1130 val = 1 << 5;
Jing Zhouff57d862017-03-21 00:54:25 -07001131 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1132 csid_reg->tpg_reg->csid_tpg_color_bars_cfg_addr);
1133 /* config pix pattern */
1134 cam_io_w_mb(csid_hw->tpg_cfg.test_pattern,
1135 soc_info->reg_map[0].mem_base +
1136 csid_reg->tpg_reg->csid_tpg_common_gen_cfg_addr);
1137
1138 return 0;
1139}
1140
1141static int cam_ife_csid_enable_csi2(
1142 struct cam_ife_csid_hw *csid_hw,
1143 struct cam_isp_resource_node *res)
1144{
1145 int rc = 0;
1146 struct cam_ife_csid_reg_offset *csid_reg;
1147 struct cam_hw_soc_info *soc_info;
1148 struct cam_ife_csid_cid_data *cid_data;
1149 uint32_t val = 0;
1150
1151 csid_reg = csid_hw->csid_info->csid_reg;
1152 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001153 CAM_DBG(CAM_ISP, "CSID:%d count:%d config csi2 rx",
1154 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001155
1156 /* overflow check before increment */
1157 if (csid_hw->csi2_cfg_cnt == UINT_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001158 CAM_ERR(CAM_ISP, "CSID:%d Open count reached max",
1159 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07001160 return -EINVAL;
1161 }
1162
1163 cid_data = (struct cam_ife_csid_cid_data *)res->res_priv;
1164
1165 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1166 csid_hw->csi2_cfg_cnt++;
1167 if (csid_hw->csi2_cfg_cnt > 1)
1168 return rc;
1169
1170 /* rx cfg0 */
1171 val = (csid_hw->csi2_rx_cfg.lane_num - 1) |
1172 (csid_hw->csi2_rx_cfg.lane_cfg << 4) |
1173 (csid_hw->csi2_rx_cfg.lane_type << 24);
Alex Wong78578602017-07-07 19:51:43 -07001174 val |= (csid_hw->csi2_rx_cfg.phy_sel & 0x3) << 20;
Jing Zhouff57d862017-03-21 00:54:25 -07001175 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1176 csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
1177
1178 /* rx cfg1*/
1179 val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
1180 /* if VC value is more than 3 than set full width of VC */
1181 if (cid_data->vc > 3)
1182 val |= (1 << csid_reg->csi2_reg->csi2_vc_mode_shift_val);
1183
1184 /* enable packet ecc correction */
1185 val |= 1;
1186 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1187 csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
1188
1189 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG) {
1190 /* Config the TPG */
1191 rc = cam_ife_csid_config_tpg(csid_hw, res);
1192 if (rc) {
1193 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1194 return rc;
1195 }
1196 }
1197
1198 /*Enable the CSI2 rx inerrupts */
1199 val = CSID_CSI2_RX_INFO_RST_DONE |
1200 CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW |
1201 CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW |
1202 CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW |
1203 CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW |
1204 CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW |
1205 CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION |
1206 CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION |
1207 CSID_CSI2_RX_ERROR_CPHY_PH_CRC;
1208 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1209 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1210
1211 return 0;
1212}
1213
1214static int cam_ife_csid_disable_csi2(
1215 struct cam_ife_csid_hw *csid_hw,
1216 struct cam_isp_resource_node *res)
1217{
1218 struct cam_ife_csid_reg_offset *csid_reg;
1219 struct cam_hw_soc_info *soc_info;
1220
1221 if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001222 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
1223 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001224 return -EINVAL;
1225 }
1226
1227 csid_reg = csid_hw->csid_info->csid_reg;
1228 soc_info = &csid_hw->hw_info->soc_info;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001229 CAM_DBG(CAM_ISP, "CSID:%d cnt : %d Disable csi2 rx",
1230 csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
Jing Zhouff57d862017-03-21 00:54:25 -07001231
1232 if (csid_hw->csi2_cfg_cnt)
1233 csid_hw->csi2_cfg_cnt--;
1234
1235 if (csid_hw->csi2_cfg_cnt)
1236 return 0;
1237
1238 /*Disable the CSI2 rx inerrupts */
1239 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1240 csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
1241
1242 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1243
1244 return 0;
1245}
1246
1247static int cam_ife_csid_init_config_ipp_path(
1248 struct cam_ife_csid_hw *csid_hw,
1249 struct cam_isp_resource_node *res)
1250{
1251 int rc = 0;
1252 struct cam_ife_csid_path_cfg *path_data;
1253 struct cam_ife_csid_reg_offset *csid_reg;
1254 struct cam_hw_soc_info *soc_info;
Harsh Shahf7136392017-08-29 12:42:52 -07001255 uint32_t decode_format = 0, plain_format = 0, val = 0;
Jing Zhouff57d862017-03-21 00:54:25 -07001256
1257 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1258 csid_reg = csid_hw->csid_info->csid_reg;
1259 soc_info = &csid_hw->hw_info->soc_info;
1260
1261 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001262 CAM_ERR(CAM_ISP, "CSID:%d IPP:%d is not supported on HW",
1263 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001264 res->res_id);
1265 return -EINVAL;
1266 }
1267
Harsh Shahf7136392017-08-29 12:42:52 -07001268 CAM_DBG(CAM_ISP, "Config IPP Path");
1269 rc = cam_ife_csid_get_format_ipp(path_data->in_format,
1270 &decode_format, &plain_format);
Jing Zhouff57d862017-03-21 00:54:25 -07001271 if (rc)
1272 return rc;
1273
Jing Zhoubb536a82017-05-18 15:20:38 -07001274 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001275 * configure the IPP and enable the time stamp capture.
1276 * enable the HW measrurement blocks
1277 */
1278 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1279 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1280 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
Harsh Shahf7136392017-08-29 12:42:52 -07001281 (decode_format << csid_reg->cmn_reg->fmt_shift_val) |
Jing Zhouff57d862017-03-21 00:54:25 -07001282 (path_data->crop_enable & 1 <<
1283 csid_reg->cmn_reg->crop_h_en_shift_val) |
1284 (path_data->crop_enable & 1 <<
1285 csid_reg->cmn_reg->crop_v_en_shift_val) |
1286 (1 << 1) | 1;
1287 val |= (1 << csid_reg->ipp_reg->pix_store_en_shift_val);
1288 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1289 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1290
Jing Zhoudedc4762017-06-19 17:45:36 +05301291 /* select the post irq sub sample strobe for time stamp capture */
1292 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1293 csid_reg->ipp_reg->csid_ipp_cfg1_addr);
1294
Jing Zhouff57d862017-03-21 00:54:25 -07001295 if (path_data->crop_enable) {
1296 val = ((path_data->width +
1297 path_data->start_pixel) & 0xFFFF <<
1298 csid_reg->cmn_reg->crop_shift) |
1299 (path_data->start_pixel & 0xFFFF);
1300
1301 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1302 csid_reg->ipp_reg->csid_ipp_hcrop_addr);
1303
1304 val = ((path_data->height +
1305 path_data->start_line) & 0xFFFF <<
1306 csid_reg->cmn_reg->crop_shift) |
1307 (path_data->start_line & 0xFFFF);
1308
1309 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1310 csid_reg->ipp_reg->csid_ipp_vcrop_addr);
1311 }
1312
1313 /* set frame drop pattern to 0 and period to 1 */
1314 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1315 csid_reg->ipp_reg->csid_ipp_frm_drop_period_addr);
1316 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1317 csid_reg->ipp_reg->csid_ipp_frm_drop_pattern_addr);
1318 /* set irq sub sample pattern to 0 and period to 1 */
1319 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1320 csid_reg->ipp_reg->csid_ipp_irq_subsample_period_addr);
1321 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1322 csid_reg->ipp_reg->csid_ipp_irq_subsample_pattern_addr);
1323 /* set pixel drop pattern to 0 and period to 1 */
1324 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1325 csid_reg->ipp_reg->csid_ipp_pix_drop_pattern_addr);
1326 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1327 csid_reg->ipp_reg->csid_ipp_pix_drop_period_addr);
1328 /* set line drop pattern to 0 and period to 1 */
1329 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1330 csid_reg->ipp_reg->csid_ipp_line_drop_pattern_addr);
1331 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1332 csid_reg->ipp_reg->csid_ipp_line_drop_period_addr);
1333
1334 /*Set master or slave IPP */
1335 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
1336 /*Set halt mode as master */
1337 val = CSID_HALT_MODE_MASTER << 2;
1338 else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
1339 /*Set halt mode as slave and set master idx */
1340 val = path_data->master_idx << 4 | CSID_HALT_MODE_SLAVE << 2;
1341 else
1342 /* Default is internal halt mode */
1343 val = 0;
1344
1345 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1346 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1347
1348 /* Enable the IPP path */
1349 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1350 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1351 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
1352 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1353 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1354
1355 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1356
1357 return rc;
1358}
1359
1360static int cam_ife_csid_deinit_ipp_path(
1361 struct cam_ife_csid_hw *csid_hw,
1362 struct cam_isp_resource_node *res)
1363{
1364 int rc = 0;
1365 struct cam_ife_csid_reg_offset *csid_reg;
1366 struct cam_hw_soc_info *soc_info;
1367 uint32_t val = 0;
1368
1369 csid_reg = csid_hw->csid_info->csid_reg;
1370 soc_info = &csid_hw->hw_info->soc_info;
1371
1372 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001373 CAM_ERR(CAM_ISP,
1374 "CSID:%d Res type %d res_id:%d in wrong state %d",
1375 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001376 res->res_type, res->res_id, res->res_state);
1377 rc = -EINVAL;
1378 }
1379
1380 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001381 CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW",
1382 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001383 res->res_id);
1384 rc = -EINVAL;
1385 }
1386
1387 /* Disable the IPP path */
1388 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1389 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1390 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1391 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1392 csid_reg->ipp_reg->csid_ipp_cfg0_addr);
1393
1394 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1395 return rc;
1396}
1397
1398static int cam_ife_csid_enable_ipp_path(
1399 struct cam_ife_csid_hw *csid_hw,
1400 struct cam_isp_resource_node *res)
1401{
1402 struct cam_ife_csid_reg_offset *csid_reg;
1403 struct cam_hw_soc_info *soc_info;
1404 struct cam_ife_csid_path_cfg *path_data;
1405 uint32_t val = 0;
1406
1407 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1408 csid_reg = csid_hw->csid_info->csid_reg;
1409 soc_info = &csid_hw->hw_info->soc_info;
1410
1411 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001412 CAM_ERR(CAM_ISP,
1413 "CSID:%d res type:%d res_id:%d Invalid state%d",
1414 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001415 res->res_type, res->res_id, res->res_state);
1416 return -EINVAL;
1417 }
1418
1419 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001420 CAM_ERR(CAM_ISP, "CSID:%d IPP %d not supported on HW",
1421 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001422 res->res_id);
1423 return -EINVAL;
1424 }
1425
Harsh Shahf7136392017-08-29 12:42:52 -07001426 CAM_DBG(CAM_ISP, "Enable IPP path");
Jing Zhouff57d862017-03-21 00:54:25 -07001427
Harsh Shahf7136392017-08-29 12:42:52 -07001428 /* Resume at frame boundary */
Jing Zhouff57d862017-03-21 00:54:25 -07001429 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1430 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1431 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1432 val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
1433 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1434 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1435 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
1436 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1437 soc_info->reg_map[0].mem_base +
1438 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1439 }
1440 /* for slave mode, not need to resume for slave device */
1441
1442 /* Enable the required ipp interrupts */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301443 val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
Jing Zhouff57d862017-03-21 00:54:25 -07001444 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1445 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1446
1447 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1448
1449 return 0;
1450}
1451
1452static int cam_ife_csid_disable_ipp_path(
1453 struct cam_ife_csid_hw *csid_hw,
1454 struct cam_isp_resource_node *res,
1455 enum cam_ife_csid_halt_cmd stop_cmd)
1456{
1457 int rc = 0;
1458 struct cam_ife_csid_reg_offset *csid_reg;
1459 struct cam_hw_soc_info *soc_info;
1460 struct cam_ife_csid_path_cfg *path_data;
1461 uint32_t val = 0;
1462
1463 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1464 csid_reg = csid_hw->csid_info->csid_reg;
1465 soc_info = &csid_hw->hw_info->soc_info;
1466
1467 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001468 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1469 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001470 return -EINVAL;
1471 }
1472
1473 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1474 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001475 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1476 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001477 res->res_id, res->res_state);
1478 return rc;
1479 }
1480
1481 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001482 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1483 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001484 res->res_state);
1485 return -EINVAL;
1486 }
1487
1488 if (!csid_reg->ipp_reg) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001489 CAM_ERR(CAM_ISP, "CSID:%d IPP%d is not supported on HW",
1490 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001491 return -EINVAL;
1492 }
1493
1494 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1495 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001496 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1497 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001498 return -EINVAL;
1499 }
1500
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001501 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001502 csid_hw->hw_intf->hw_idx, res->res_id);
1503
1504 if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
1505 /* configure Halt */
1506 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1507 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1508 val &= ~0x3;
1509 val |= stop_cmd;
1510 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1511 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1512 } else if (path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
1513 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1514 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
1515
1516 /* For slave mode, halt command should take it from master */
1517
1518 /* Enable the EOF interrupt for resume at boundary case */
1519 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1520 init_completion(&csid_hw->csid_ipp_complete);
1521 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1522 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1523 val |= CSID_PATH_INFO_INPUT_EOF;
1524 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1525 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1526 } else {
1527 val &= ~(CSID_PATH_INFO_RST_DONE |
Harsh Shahf7136392017-08-29 12:42:52 -07001528 CSID_PATH_ERROR_FIFO_OVERFLOW);
Jing Zhouff57d862017-03-21 00:54:25 -07001529 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1530 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1531 }
1532
1533 return rc;
1534}
1535
1536
1537static int cam_ife_csid_init_config_rdi_path(
1538 struct cam_ife_csid_hw *csid_hw,
1539 struct cam_isp_resource_node *res)
1540{
1541 int rc = 0;
1542 struct cam_ife_csid_path_cfg *path_data;
1543 struct cam_ife_csid_reg_offset *csid_reg;
1544 struct cam_hw_soc_info *soc_info;
1545 uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
1546
1547 path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
1548 csid_reg = csid_hw->csid_info->csid_reg;
1549 soc_info = &csid_hw->hw_info->soc_info;
1550
1551 id = res->res_id;
1552 if (!csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001553 CAM_ERR(CAM_ISP, "CSID:%d RDI:%d is not supported on HW",
1554 csid_hw->hw_intf->hw_idx, id);
Jing Zhouff57d862017-03-21 00:54:25 -07001555 return -EINVAL;
1556 }
1557
Harsh Shahf7136392017-08-29 12:42:52 -07001558 rc = cam_ife_csid_get_format_rdi(path_data->in_format,
1559 path_data->out_format, &path_format, &plain_fmt);
Jing Zhouff57d862017-03-21 00:54:25 -07001560 if (rc)
1561 return rc;
1562
Jing Zhoubb536a82017-05-18 15:20:38 -07001563 /*
Jing Zhouff57d862017-03-21 00:54:25 -07001564 * RDI path config and enable the time stamp capture
1565 * Enable the measurement blocks
1566 */
1567 val = (path_data->vc << csid_reg->cmn_reg->vc_shift_val) |
1568 (path_data->dt << csid_reg->cmn_reg->dt_shift_val) |
1569 (path_data->cid << csid_reg->cmn_reg->dt_id_shift_val) |
1570 (path_format << csid_reg->cmn_reg->fmt_shift_val) |
1571 (plain_fmt << csid_reg->cmn_reg->plain_fmt_shit_val) |
1572 (path_data->crop_enable & 1 <<
1573 csid_reg->cmn_reg->crop_h_en_shift_val) |
1574 (path_data->crop_enable & 1 <<
1575 csid_reg->cmn_reg->crop_v_en_shift_val) |
1576 (1 << 2) | 3;
1577
1578 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1579 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1580
Jing Zhoudedc4762017-06-19 17:45:36 +05301581 /* select the post irq sub sample strobe for time stamp capture */
1582 cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base +
1583 csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr);
1584
Jing Zhouff57d862017-03-21 00:54:25 -07001585 if (path_data->crop_enable) {
1586 val = ((path_data->width +
1587 path_data->start_pixel) & 0xFFFF <<
1588 csid_reg->cmn_reg->crop_shift) |
1589 (path_data->start_pixel & 0xFFFF);
1590
1591 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1592 csid_reg->rdi_reg[id]->csid_rdi_rpp_hcrop_addr);
1593
1594 val = ((path_data->height +
1595 path_data->start_line) & 0xFFFF <<
1596 csid_reg->cmn_reg->crop_shift) |
1597 (path_data->start_line & 0xFFFF);
1598
1599 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1600 csid_reg->rdi_reg[id]->csid_rdi_rpp_vcrop_addr);
1601 }
1602 /* set frame drop pattern to 0 and period to 1 */
1603 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1604 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
1605 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1606 csid_reg->rdi_reg[id]->csid_rdi_frm_drop_pattern_addr);
1607 /* set IRQ sum sabmple */
1608 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1609 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_period_addr);
1610 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1611 csid_reg->rdi_reg[id]->csid_rdi_irq_subsample_pattern_addr);
1612
1613 /* set pixel drop pattern to 0 and period to 1 */
1614 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1615 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_pattern_addr);
1616 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1617 csid_reg->rdi_reg[id]->csid_rdi_rpp_pix_drop_period_addr);
1618 /* set line drop pattern to 0 and period to 1 */
1619 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1620 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_pattern_addr);
1621 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
1622 csid_reg->rdi_reg[id]->csid_rdi_rpp_line_drop_period_addr);
1623
1624 /* Configure the halt mode */
1625 cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
1626 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1627
1628 /* Enable the RPP path */
1629 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1630 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1631 val |= (1 << csid_reg->cmn_reg->path_en_shift_val);
Harsh Shahf7136392017-08-29 12:42:52 -07001632#if MEASURE_EN
1633 val |= 0x2;
1634 cam_io_w_mb(0x3, soc_info->reg_map[0].mem_base +
1635 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
1636 cam_io_w_mb(path_data->height << 16 | path_data->width,
1637 soc_info->reg_map[0].mem_base +
1638 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr);
1639 CAM_DBG(CAM_ISP, "measure_cfg1 0x%x offset 0x%x\n",
1640 path_data->height << 16 | path_data->width,
1641 csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
1642
1643#endif
Jing Zhouff57d862017-03-21 00:54:25 -07001644 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1645 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1646
1647 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1648
1649 return rc;
1650}
1651
1652static int cam_ife_csid_deinit_rdi_path(
1653 struct cam_ife_csid_hw *csid_hw,
1654 struct cam_isp_resource_node *res)
1655{
1656 int rc = 0;
1657 struct cam_ife_csid_reg_offset *csid_reg;
1658 struct cam_hw_soc_info *soc_info;
1659 uint32_t val = 0, id;
1660
1661 csid_reg = csid_hw->csid_info->csid_reg;
1662 soc_info = &csid_hw->hw_info->soc_info;
1663 id = res->res_id;
1664
1665 if (res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1666 res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1667 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001668 CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d state:%d",
1669 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001670 res->res_state);
1671 return -EINVAL;
1672 }
1673
1674 /* Disable the RDI path */
1675 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1676 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1677 val &= ~(1 << csid_reg->cmn_reg->path_en_shift_val);
1678 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1679 csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr);
1680
1681 res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1682 return rc;
1683}
1684
1685static int cam_ife_csid_enable_rdi_path(
1686 struct cam_ife_csid_hw *csid_hw,
1687 struct cam_isp_resource_node *res)
1688{
1689 struct cam_ife_csid_reg_offset *csid_reg;
1690 struct cam_hw_soc_info *soc_info;
1691 uint32_t id, val;
1692
1693 csid_reg = csid_hw->csid_info->csid_reg;
1694 soc_info = &csid_hw->hw_info->soc_info;
1695 id = res->res_id;
1696
1697 if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW ||
1698 res->res_id > CAM_IFE_PIX_PATH_RES_RDI_3 ||
1699 !csid_reg->rdi_reg[id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001700 CAM_ERR(CAM_ISP,
1701 "CSID:%d invalid res type:%d res_id:%d state%d",
1702 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001703 res->res_type, res->res_id, res->res_state);
1704 return -EINVAL;
1705 }
1706
1707 /*resume at frame boundary */
1708 cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
1709 soc_info->reg_map[0].mem_base +
1710 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1711
1712 /* Enable the required RDI interrupts */
Harsh Shahf7136392017-08-29 12:42:52 -07001713 val = CSID_PATH_INFO_RST_DONE |
1714#if MEASURE_EN
1715 CSID_PATH_INFO_INPUT_SOF |
1716#endif
1717 CSID_PATH_ERROR_FIFO_OVERFLOW;
Jing Zhouff57d862017-03-21 00:54:25 -07001718 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1719 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1720
1721 res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1722
1723 return 0;
1724}
1725
1726
1727static int cam_ife_csid_disable_rdi_path(
1728 struct cam_ife_csid_hw *csid_hw,
1729 struct cam_isp_resource_node *res,
1730 enum cam_ife_csid_halt_cmd stop_cmd)
1731{
1732 int rc = 0;
1733 struct cam_ife_csid_reg_offset *csid_reg;
1734 struct cam_hw_soc_info *soc_info;
1735 uint32_t val = 0, id;
1736
1737 csid_reg = csid_hw->csid_info->csid_reg;
1738 soc_info = &csid_hw->hw_info->soc_info;
1739 id = res->res_id;
1740
1741 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX ||
1742 !csid_reg->rdi_reg[res->res_id]) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001743 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1744 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001745 return -EINVAL;
1746 }
1747
1748 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1749 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001750 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1751 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001752 res->res_id, res->res_state);
1753 return rc;
1754 }
1755
1756 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001757 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid res_state%d",
1758 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001759 res->res_state);
1760 return -EINVAL;
1761 }
1762
1763 if (stop_cmd != CAM_CSID_HALT_AT_FRAME_BOUNDARY &&
1764 stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001765 CAM_ERR(CAM_ISP, "CSID:%d un supported stop command:%d",
1766 csid_hw->hw_intf->hw_idx, stop_cmd);
Jing Zhouff57d862017-03-21 00:54:25 -07001767 return -EINVAL;
1768 }
1769
1770
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001771 CAM_DBG(CAM_ISP, "CSID:%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07001772 csid_hw->hw_intf->hw_idx, res->res_id);
1773
1774 init_completion(&csid_hw->csid_rdin_complete[id]);
1775
1776 if (stop_cmd != CAM_CSID_HALT_IMMEDIATELY) {
1777 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1778 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1779 val |= CSID_PATH_INFO_INPUT_EOF;
1780 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1781 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1782 } else {
1783 val &= ~(CSID_PATH_INFO_RST_DONE |
1784 CSID_PATH_ERROR_FIFO_OVERFLOW);
1785 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1786 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1787 }
1788
1789 /*Halt the RDI path */
1790 cam_io_w_mb(stop_cmd, soc_info->reg_map[0].mem_base +
1791 csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
1792
1793 return rc;
1794}
1795
1796static int cam_ife_csid_get_time_stamp(
1797 struct cam_ife_csid_hw *csid_hw, void *cmd_args)
1798{
1799 struct cam_csid_get_time_stamp_args *time_stamp;
1800 struct cam_isp_resource_node *res;
1801 struct cam_ife_csid_reg_offset *csid_reg;
1802 struct cam_hw_soc_info *soc_info;
1803 uint32_t time_32, id;
1804
1805 time_stamp = (struct cam_csid_get_time_stamp_args *)cmd_args;
1806 res = time_stamp->node_res;
1807 csid_reg = csid_hw->csid_info->csid_reg;
1808 soc_info = &csid_hw->hw_info->soc_info;
1809
1810 if (res->res_type != CAM_ISP_RESOURCE_PIX_PATH ||
1811 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001812 CAM_DBG(CAM_ISP, "CSID:%d Invalid res_type:%d res id%d",
1813 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07001814 res->res_id);
1815 return -EINVAL;
1816 }
1817
1818 if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001819 CAM_ERR(CAM_ISP, "CSID:%d Invalid dev state :%d",
1820 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001821 csid_hw->hw_info->hw_state);
1822 return -EINVAL;
1823 }
1824
1825 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1826 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1827 csid_reg->ipp_reg->csid_ipp_timestamp_curr1_sof_addr);
1828 time_stamp->time_stamp_val = time_32;
1829 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1830 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1831 csid_reg->ipp_reg->csid_ipp_timestamp_curr0_sof_addr);
1832 time_stamp->time_stamp_val |= time_32;
1833 } else {
1834 id = res->res_id;
1835 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1836 csid_reg->rdi_reg[id]->
1837 csid_rdi_timestamp_curr1_sof_addr);
1838 time_stamp->time_stamp_val = time_32;
1839 time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
1840
1841 time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1842 csid_reg->rdi_reg[id]->
1843 csid_rdi_timestamp_curr0_sof_addr);
1844 time_stamp->time_stamp_val |= time_32;
1845 }
1846
1847 return 0;
1848}
1849static int cam_ife_csid_res_wait_for_halt(
1850 struct cam_ife_csid_hw *csid_hw,
1851 struct cam_isp_resource_node *res)
1852{
1853 int rc = 0;
1854 struct cam_ife_csid_reg_offset *csid_reg;
1855 struct cam_hw_soc_info *soc_info;
1856
1857 struct completion *complete;
1858 uint32_t val = 0, id;
1859
1860 csid_reg = csid_hw->csid_info->csid_reg;
1861 soc_info = &csid_hw->hw_info->soc_info;
1862
1863 if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001864 CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
1865 csid_hw->hw_intf->hw_idx, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07001866 return -EINVAL;
1867 }
1868
1869 if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
1870 res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001871 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
1872 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001873 res->res_id, res->res_state);
1874 return rc;
1875 }
1876
1877 if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001878 CAM_DBG(CAM_ISP, "CSID:%d Res:%d Invalid state%d",
1879 csid_hw->hw_intf->hw_idx, res->res_id,
Jing Zhouff57d862017-03-21 00:54:25 -07001880 res->res_state);
1881 return -EINVAL;
1882 }
1883
1884 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
1885 complete = &csid_hw->csid_ipp_complete;
1886 else
1887 complete = &csid_hw->csid_rdin_complete[res->res_id];
1888
1889 rc = wait_for_completion_timeout(complete,
1890 msecs_to_jiffies(IFE_CSID_TIMEOUT));
1891 if (rc <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001892 CAM_ERR(CAM_ISP, "CSID%d stop at frame boundary failid:%drc:%d",
1893 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07001894 res->res_id, rc);
1895 if (rc == 0)
1896 /* continue even have timeout */
1897 rc = -ETIMEDOUT;
1898 }
1899
1900 /* Disable the interrupt */
1901 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
1902 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1903 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1904 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1905 CSID_PATH_ERROR_FIFO_OVERFLOW);
1906 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1907 csid_reg->ipp_reg->csid_ipp_irq_mask_addr);
1908 } else {
1909 id = res->res_id;
1910 val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
1911 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1912 val &= ~(CSID_PATH_INFO_INPUT_EOF | CSID_PATH_INFO_RST_DONE |
1913 CSID_PATH_ERROR_FIFO_OVERFLOW);
1914 cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
1915 csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
1916 }
1917 /* set state to init HW */
1918 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
1919 return rc;
1920}
1921
1922static int cam_ife_csid_get_hw_caps(void *hw_priv,
1923 void *get_hw_cap_args, uint32_t arg_size)
1924{
1925 int rc = 0;
1926 struct cam_ife_csid_hw_caps *hw_caps;
1927 struct cam_ife_csid_hw *csid_hw;
1928 struct cam_hw_info *csid_hw_info;
1929 struct cam_ife_csid_reg_offset *csid_reg;
1930
1931 if (!hw_priv || !get_hw_cap_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001932 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07001933 return -EINVAL;
1934 }
1935
1936 csid_hw_info = (struct cam_hw_info *)hw_priv;
1937 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
1938 csid_reg = csid_hw->csid_info->csid_reg;
1939 hw_caps = (struct cam_ife_csid_hw_caps *) get_hw_cap_args;
1940
1941 hw_caps->no_rdis = csid_reg->cmn_reg->no_rdis;
1942 hw_caps->no_pix = csid_reg->cmn_reg->no_pix;
1943 hw_caps->major_version = csid_reg->cmn_reg->major_version;
1944 hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
1945 hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
1946
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001947 CAM_DBG(CAM_ISP,
1948 "CSID:%d No rdis:%d, no pix:%d, major:%d minor:%d ver :%d",
1949 csid_hw->hw_intf->hw_idx, hw_caps->no_rdis,
Jing Zhouff57d862017-03-21 00:54:25 -07001950 hw_caps->no_pix, hw_caps->major_version, hw_caps->minor_version,
1951 hw_caps->version_incr);
1952
1953 return rc;
1954}
1955
1956static int cam_ife_csid_reset(void *hw_priv,
1957 void *reset_args, uint32_t arg_size)
1958{
1959 struct cam_ife_csid_hw *csid_hw;
1960 struct cam_hw_info *csid_hw_info;
1961 struct cam_csid_reset_cfg_args *reset;
1962 int rc = 0;
1963
1964 if (!hw_priv || !reset_args || (arg_size !=
1965 sizeof(struct cam_csid_reset_cfg_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001966 CAM_ERR(CAM_ISP, "CSID:Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07001967 return -EINVAL;
1968 }
1969
1970 csid_hw_info = (struct cam_hw_info *)hw_priv;
1971 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
1972 reset = (struct cam_csid_reset_cfg_args *)reset_args;
1973
1974 switch (reset->reset_type) {
1975 case CAM_IFE_CSID_RESET_GLOBAL:
1976 rc = cam_ife_csid_global_reset(csid_hw);
1977 break;
1978 case CAM_IFE_CSID_RESET_PATH:
1979 rc = cam_ife_csid_path_reset(csid_hw, reset);
1980 break;
1981 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001982 CAM_ERR(CAM_ISP, "CSID:Invalid reset type :%d",
1983 reset->reset_type);
Jing Zhouff57d862017-03-21 00:54:25 -07001984 rc = -EINVAL;
1985 break;
1986 }
1987
1988 return rc;
1989}
1990
1991static int cam_ife_csid_reserve(void *hw_priv,
1992 void *reserve_args, uint32_t arg_size)
1993{
1994 int rc = 0;
1995 struct cam_ife_csid_hw *csid_hw;
1996 struct cam_hw_info *csid_hw_info;
1997 struct cam_csid_hw_reserve_resource_args *reserv;
1998
1999 if (!hw_priv || !reserve_args || (arg_size !=
2000 sizeof(struct cam_csid_hw_reserve_resource_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002001 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002002 return -EINVAL;
2003 }
2004
2005 csid_hw_info = (struct cam_hw_info *)hw_priv;
2006 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2007 reserv = (struct cam_csid_hw_reserve_resource_args *)reserve_args;
2008
2009 mutex_lock(&csid_hw->hw_info->hw_mutex);
2010 switch (reserv->res_type) {
2011 case CAM_ISP_RESOURCE_CID:
2012 rc = cam_ife_csid_cid_reserve(csid_hw, reserv);
2013 break;
2014 case CAM_ISP_RESOURCE_PIX_PATH:
2015 rc = cam_ife_csid_path_reserve(csid_hw, reserv);
2016 break;
2017 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002018 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type :%d",
2019 csid_hw->hw_intf->hw_idx, reserv->res_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002020 rc = -EINVAL;
2021 break;
2022 }
2023 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2024 return rc;
2025}
2026
2027static int cam_ife_csid_release(void *hw_priv,
2028 void *release_args, uint32_t arg_size)
2029{
2030 int rc = 0;
2031 struct cam_ife_csid_hw *csid_hw;
2032 struct cam_hw_info *csid_hw_info;
2033 struct cam_isp_resource_node *res;
2034 struct cam_ife_csid_cid_data *cid_data;
2035
2036 if (!hw_priv || !release_args ||
2037 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002038 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002039 return -EINVAL;
2040 }
2041
2042 csid_hw_info = (struct cam_hw_info *)hw_priv;
2043 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2044 res = (struct cam_isp_resource_node *)release_args;
2045
2046 mutex_lock(&csid_hw->hw_info->hw_mutex);
2047 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2048 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2049 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2050 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002051 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2052 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002053 res->res_id);
2054 rc = -EINVAL;
2055 goto end;
2056 }
2057
2058 if (res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002059 CAM_DBG(CAM_ISP,
2060 "CSID:%d res type:%d Res %d in released state",
2061 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002062 res->res_type, res->res_id);
2063 goto end;
2064 }
2065
2066 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2067 res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002068 CAM_DBG(CAM_ISP,
2069 "CSID:%d res type:%d Res id:%d invalid state:%d",
2070 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002071 res->res_type, res->res_id, res->res_state);
2072 rc = -EINVAL;
2073 goto end;
2074 }
2075
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002076 CAM_DBG(CAM_ISP, "CSID:%d res type :%d Resource id:%d",
2077 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
Jing Zhouff57d862017-03-21 00:54:25 -07002078
2079 switch (res->res_type) {
2080 case CAM_ISP_RESOURCE_CID:
2081 cid_data = (struct cam_ife_csid_cid_data *) res->res_priv;
2082 if (cid_data->cnt)
2083 cid_data->cnt--;
2084
2085 if (!cid_data->cnt)
2086 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2087
2088 if (csid_hw->csi2_reserve_cnt)
2089 csid_hw->csi2_reserve_cnt--;
2090
2091 if (!csid_hw->csi2_reserve_cnt)
2092 memset(&csid_hw->csi2_rx_cfg, 0,
2093 sizeof(struct cam_ife_csid_csi2_rx_cfg));
2094
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002095 CAM_DBG(CAM_ISP, "CSID:%d res id :%d cnt:%d reserv cnt:%d",
2096 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002097 res->res_id, cid_data->cnt, csid_hw->csi2_reserve_cnt);
2098
2099 break;
2100 case CAM_ISP_RESOURCE_PIX_PATH:
2101 res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2102 break;
2103 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002104 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
2105 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002106 res->res_id);
2107 rc = -EINVAL;
2108 break;
2109 }
2110
2111end:
2112 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2113 return rc;
2114}
2115
2116static int cam_ife_csid_init_hw(void *hw_priv,
2117 void *init_args, uint32_t arg_size)
2118{
2119 int rc = 0;
2120 struct cam_ife_csid_hw *csid_hw;
2121 struct cam_hw_info *csid_hw_info;
2122 struct cam_isp_resource_node *res;
2123 struct cam_ife_csid_reg_offset *csid_reg;
2124
2125 if (!hw_priv || !init_args ||
2126 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002127 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002128 return -EINVAL;
2129 }
2130
2131 csid_hw_info = (struct cam_hw_info *)hw_priv;
2132 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2133 res = (struct cam_isp_resource_node *)init_args;
2134 csid_reg = csid_hw->csid_info->csid_reg;
2135
2136 mutex_lock(&csid_hw->hw_info->hw_mutex);
2137 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2138 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2139 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2140 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002141 CAM_ERR(CAM_ISP, "CSID:%d Invalid res tpe:%d res id%d",
2142 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002143 res->res_id);
2144 rc = -EINVAL;
2145 goto end;
2146 }
2147
2148
2149 if ((res->res_type == CAM_ISP_RESOURCE_PIX_PATH) &&
2150 (res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002151 CAM_ERR(CAM_ISP,
2152 "CSID:%d res type:%d res_id:%dInvalid state %d",
2153 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002154 res->res_type, res->res_id, res->res_state);
2155 rc = -EINVAL;
2156 goto end;
2157 }
2158
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002159 CAM_DBG(CAM_ISP, "CSID:%d res type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002160 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2161
2162
2163 /* Initialize the csid hardware */
2164 rc = cam_ife_csid_enable_hw(csid_hw);
2165 if (rc)
2166 goto end;
2167
2168 switch (res->res_type) {
2169 case CAM_ISP_RESOURCE_CID:
2170 rc = cam_ife_csid_enable_csi2(csid_hw, res);
2171 break;
2172 case CAM_ISP_RESOURCE_PIX_PATH:
2173 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2174 rc = cam_ife_csid_init_config_ipp_path(csid_hw, res);
2175 else
2176 rc = cam_ife_csid_init_config_rdi_path(csid_hw, res);
2177
2178 break;
2179 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002180 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type state %d",
2181 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002182 res->res_type);
2183 break;
2184 }
2185
2186 if (rc)
2187 cam_ife_csid_disable_hw(csid_hw);
2188end:
2189 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2190 return rc;
2191}
2192
2193static int cam_ife_csid_deinit_hw(void *hw_priv,
2194 void *deinit_args, uint32_t arg_size)
2195{
2196 int rc = 0;
2197 struct cam_ife_csid_hw *csid_hw;
2198 struct cam_hw_info *csid_hw_info;
2199 struct cam_isp_resource_node *res;
2200
2201 if (!hw_priv || !deinit_args ||
2202 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002203 CAM_ERR(CAM_ISP, "CSID:Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002204 return -EINVAL;
2205 }
2206
2207 res = (struct cam_isp_resource_node *)deinit_args;
2208 csid_hw_info = (struct cam_hw_info *)hw_priv;
2209 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2210
2211 mutex_lock(&csid_hw->hw_info->hw_mutex);
2212 if (res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002213 CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in De-init state",
2214 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002215 res->res_id);
2216 goto end;
2217 }
2218
2219 switch (res->res_type) {
2220 case CAM_ISP_RESOURCE_CID:
2221 rc = cam_ife_csid_disable_csi2(csid_hw, res);
2222 break;
2223 case CAM_ISP_RESOURCE_PIX_PATH:
2224 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2225 rc = cam_ife_csid_deinit_ipp_path(csid_hw, res);
2226 else
2227 rc = cam_ife_csid_deinit_rdi_path(csid_hw, res);
2228
2229 break;
2230 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002231 CAM_ERR(CAM_ISP, "CSID:%d Invalid Res type %d",
2232 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002233 res->res_type);
2234 goto end;
2235 }
2236
2237 /* Disable CSID HW */
2238 cam_ife_csid_disable_hw(csid_hw);
2239
2240end:
2241 mutex_unlock(&csid_hw->hw_info->hw_mutex);
2242 return rc;
2243}
2244
2245static int cam_ife_csid_start(void *hw_priv, void *start_args,
2246 uint32_t arg_size)
2247{
2248 int rc = 0;
2249 struct cam_ife_csid_hw *csid_hw;
2250 struct cam_hw_info *csid_hw_info;
2251 struct cam_isp_resource_node *res;
2252 struct cam_ife_csid_reg_offset *csid_reg;
2253
2254 if (!hw_priv || !start_args ||
2255 (arg_size != sizeof(struct cam_isp_resource_node))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002256 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002257 return -EINVAL;
2258 }
2259
2260 csid_hw_info = (struct cam_hw_info *)hw_priv;
2261 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2262 res = (struct cam_isp_resource_node *)start_args;
2263 csid_reg = csid_hw->csid_info->csid_reg;
2264
Jing Zhouff57d862017-03-21 00:54:25 -07002265 if ((res->res_type == CAM_ISP_RESOURCE_CID &&
2266 res->res_id >= CAM_IFE_CSID_CID_MAX) ||
2267 (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2268 res->res_id >= CAM_IFE_PIX_PATH_RES_MAX)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002269 CAM_DBG(CAM_ISP, "CSID:%d Invalid res tpe:%d res id:%d",
2270 csid_hw->hw_intf->hw_idx, res->res_type,
Jing Zhouff57d862017-03-21 00:54:25 -07002271 res->res_id);
2272 rc = -EINVAL;
2273 goto end;
2274 }
2275
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002276 CAM_DBG(CAM_ISP, "CSID:%d res_type :%d res_id:%d",
Jing Zhouff57d862017-03-21 00:54:25 -07002277 csid_hw->hw_intf->hw_idx, res->res_type, res->res_id);
2278
2279 switch (res->res_type) {
2280 case CAM_ISP_RESOURCE_CID:
2281 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2282 rc = cam_ife_csid_tpg_start(csid_hw, res);
2283 break;
2284 case CAM_ISP_RESOURCE_PIX_PATH:
2285 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2286 rc = cam_ife_csid_enable_ipp_path(csid_hw, res);
2287 else
2288 rc = cam_ife_csid_enable_rdi_path(csid_hw, res);
2289 break;
2290 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002291 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2292 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002293 res->res_type);
2294 break;
2295 }
2296end:
Jing Zhouff57d862017-03-21 00:54:25 -07002297 return rc;
2298}
2299
2300static int cam_ife_csid_stop(void *hw_priv,
2301 void *stop_args, uint32_t arg_size)
2302{
2303 int rc = 0;
2304 struct cam_ife_csid_hw *csid_hw;
2305 struct cam_hw_info *csid_hw_info;
2306 struct cam_isp_resource_node *res;
2307 struct cam_csid_hw_stop_args *csid_stop;
2308 uint32_t i;
2309
2310 if (!hw_priv || !stop_args ||
2311 (arg_size != sizeof(struct cam_csid_hw_stop_args))) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002312 CAM_ERR(CAM_ISP, "CSID: Invalid args");
Jing Zhouff57d862017-03-21 00:54:25 -07002313 return -EINVAL;
2314 }
2315 csid_stop = (struct cam_csid_hw_stop_args *) stop_args;
2316 csid_hw_info = (struct cam_hw_info *)hw_priv;
2317 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2318
Jing Zhouff57d862017-03-21 00:54:25 -07002319 /* Stop the resource first */
2320 for (i = 0; i < csid_stop->num_res; i++) {
2321 res = csid_stop->node_res[i];
2322 switch (res->res_type) {
2323 case CAM_ISP_RESOURCE_CID:
2324 if (csid_hw->res_type == CAM_ISP_IFE_IN_RES_TPG)
2325 rc = cam_ife_csid_tpg_stop(csid_hw, res);
2326 break;
2327 case CAM_ISP_RESOURCE_PIX_PATH:
2328 if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
2329 rc = cam_ife_csid_disable_ipp_path(csid_hw,
2330 res, csid_stop->stop_cmd);
2331 else
2332 rc = cam_ife_csid_disable_rdi_path(csid_hw,
2333 res, csid_stop->stop_cmd);
2334
2335 break;
2336 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002337 CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
2338 csid_hw->hw_intf->hw_idx,
Jing Zhouff57d862017-03-21 00:54:25 -07002339 res->res_type);
2340 break;
2341 }
2342 }
2343
2344 /*wait for the path to halt */
2345 for (i = 0; i < csid_stop->num_res; i++) {
2346 res = csid_stop->node_res[i];
2347 if (res->res_type == CAM_ISP_RESOURCE_PIX_PATH &&
2348 csid_stop->stop_cmd == CAM_CSID_HALT_AT_FRAME_BOUNDARY)
2349 rc = cam_ife_csid_res_wait_for_halt(csid_hw, res);
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302350 else
2351 res->res_state = CAM_ISP_RESOURCE_STATE_INIT_HW;
Jing Zhouff57d862017-03-21 00:54:25 -07002352 }
2353
Jing Zhouff57d862017-03-21 00:54:25 -07002354 return rc;
2355
2356}
2357
2358static int cam_ife_csid_read(void *hw_priv,
2359 void *read_args, uint32_t arg_size)
2360{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002361 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002362
2363 return -EINVAL;
2364}
2365
2366static int cam_ife_csid_write(void *hw_priv,
2367 void *write_args, uint32_t arg_size)
2368{
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002369 CAM_ERR(CAM_ISP, "CSID: un supported");
Jing Zhouff57d862017-03-21 00:54:25 -07002370 return -EINVAL;
2371}
2372
2373static int cam_ife_csid_process_cmd(void *hw_priv,
2374 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2375{
2376 int rc = 0;
2377 struct cam_ife_csid_hw *csid_hw;
2378 struct cam_hw_info *csid_hw_info;
2379
2380 if (!hw_priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002381 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002382 return -EINVAL;
2383 }
2384
2385 csid_hw_info = (struct cam_hw_info *)hw_priv;
2386 csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info;
2387
Jing Zhouff57d862017-03-21 00:54:25 -07002388 switch (cmd_type) {
2389 case CAM_IFE_CSID_CMD_GET_TIME_STAMP:
2390 rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args);
2391 break;
2392 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002393 CAM_ERR(CAM_ISP, "CSID:%d un supported cmd:%d",
2394 csid_hw->hw_intf->hw_idx, cmd_type);
Jing Zhouff57d862017-03-21 00:54:25 -07002395 rc = -EINVAL;
2396 break;
2397 }
Jing Zhouff57d862017-03-21 00:54:25 -07002398
2399 return rc;
2400
2401}
2402
2403irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
2404{
2405 struct cam_ife_csid_hw *csid_hw;
2406 struct cam_hw_soc_info *soc_info;
2407 struct cam_ife_csid_reg_offset *csid_reg;
2408 uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0,
2409 irq_status_rdi[4];
Harsh Shahf7136392017-08-29 12:42:52 -07002410#if MEASURE_EN
2411 uint32_t val;
2412#endif
Jing Zhouff57d862017-03-21 00:54:25 -07002413
2414 csid_hw = (struct cam_ife_csid_hw *)data;
2415
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002416 CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002417
2418 if (!data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002419 CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
Jing Zhouff57d862017-03-21 00:54:25 -07002420 return IRQ_HANDLED;
2421 }
2422
2423 csid_reg = csid_hw->csid_info->csid_reg;
2424 soc_info = &csid_hw->hw_info->soc_info;
2425
2426 /* read */
2427 irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2428 csid_reg->cmn_reg->csid_top_irq_status_addr);
2429
2430 irq_status_rx = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2431 csid_reg->csi2_reg->csid_csi2_rx_irq_status_addr);
2432
2433 if (csid_reg->cmn_reg->no_pix)
2434 irq_status_ipp = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2435 csid_reg->ipp_reg->csid_ipp_irq_status_addr);
2436
2437
2438 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++)
2439 irq_status_rdi[i] = cam_io_r_mb(soc_info->reg_map[0].mem_base +
2440 csid_reg->rdi_reg[i]->csid_rdi_irq_status_addr);
2441
2442 /* clear */
2443 cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
2444 csid_reg->cmn_reg->csid_top_irq_clear_addr);
2445 cam_io_w_mb(irq_status_rx, soc_info->reg_map[0].mem_base +
2446 csid_reg->csi2_reg->csid_csi2_rx_irq_clear_addr);
2447 if (csid_reg->cmn_reg->no_pix)
2448 cam_io_w_mb(irq_status_ipp, soc_info->reg_map[0].mem_base +
2449 csid_reg->ipp_reg->csid_ipp_irq_clear_addr);
2450
2451 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2452 cam_io_w_mb(irq_status_rdi[i], soc_info->reg_map[0].mem_base +
2453 csid_reg->rdi_reg[i]->csid_rdi_irq_clear_addr);
2454 }
2455 cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
2456 csid_reg->cmn_reg->csid_irq_cmd_addr);
2457
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002458 CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
2459 CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
Jing Zhouff57d862017-03-21 00:54:25 -07002460
2461 if (irq_status_top) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002462 CAM_DBG(CAM_ISP, "CSID global reset complete......Exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002463 complete(&csid_hw->csid_top_complete);
2464 return IRQ_HANDLED;
2465 }
2466
2467
2468 if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002469 CAM_DBG(CAM_ISP, "csi rx reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002470 complete(&csid_hw->csid_csi2_complete);
2471 }
2472
2473 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002474 pr_err_ratelimited("CSID:%d lane 0 over flow",
2475 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002476 }
2477 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002478 pr_err_ratelimited("CSID:%d lane 1 over flow",
2479 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002480 }
2481 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002482 pr_err_ratelimited("CSID:%d lane 2 over flow",
2483 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002484 }
2485 if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002486 pr_err_ratelimited("CSID:%d lane 3 over flow",
2487 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002488 }
2489 if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002490 pr_err_ratelimited("CSID:%d TG OVER FLOW",
2491 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002492 }
2493 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002494 pr_err_ratelimited("CSID:%d CPHY_EOT_RECEPTION",
2495 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002496 }
2497 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002498 pr_err_ratelimited("CSID:%d CPHY_SOT_RECEPTION",
2499 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002500 }
2501 if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002502 pr_err_ratelimited("CSID:%d CPHY_PH_CRC",
2503 csid_hw->hw_intf->hw_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002504 }
2505
2506 /*read the IPP errors */
2507 if (csid_reg->cmn_reg->no_pix) {
2508 /* IPP reset done bit */
2509 if (irq_status_ipp &
2510 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002511 CAM_DBG(CAM_ISP, "CSID IPP reset complete");
Jing Zhouff57d862017-03-21 00:54:25 -07002512 complete(&csid_hw->csid_ipp_complete);
2513 }
2514 if (irq_status_ipp & CSID_PATH_INFO_INPUT_SOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002515 CAM_DBG(CAM_ISP, "CSID IPP SOF received");
Jing Zhouff57d862017-03-21 00:54:25 -07002516 if (irq_status_ipp & CSID_PATH_INFO_INPUT_SOL)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002517 CAM_DBG(CAM_ISP, "CSID IPP SOL received");
Jing Zhouff57d862017-03-21 00:54:25 -07002518 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOL)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002519 CAM_DBG(CAM_ISP, "CSID IPP EOL received");
Jing Zhouff57d862017-03-21 00:54:25 -07002520 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002521 CAM_DBG(CAM_ISP, "CSID IPP EOF received");
Jing Zhouff57d862017-03-21 00:54:25 -07002522
2523 if (irq_status_ipp & CSID_PATH_INFO_INPUT_EOF)
2524 complete(&csid_hw->csid_ipp_complete);
2525
2526 if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002527 CAM_ERR(CAM_ISP, "CSID:%d IPP fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002528 csid_hw->hw_intf->hw_idx);
2529 /*Stop IPP path immediately */
2530 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2531 soc_info->reg_map[0].mem_base +
2532 csid_reg->ipp_reg->csid_ipp_ctrl_addr);
2533 }
2534 }
2535
2536 for (i = 0; i < csid_reg->cmn_reg->no_rdis; i++) {
2537 if (irq_status_rdi[i] &
2538 BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002539 CAM_DBG(CAM_ISP, "CSID rdi%d reset complete", i);
Jing Zhouff57d862017-03-21 00:54:25 -07002540 complete(&csid_hw->csid_rdin_complete[i]);
2541 }
2542
Harsh Shahf7136392017-08-29 12:42:52 -07002543 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002544 CAM_DBG(CAM_ISP, "CSID RDI SOF received");
Harsh Shahf7136392017-08-29 12:42:52 -07002545#if MEASURE_EN
2546 val = cam_io_r(soc_info->reg_map[0].mem_base +
2547 csid_reg->rdi_reg[i]->
2548 csid_rdi_format_measure0_addr);
2549 CAM_ERR(CAM_ISP, "measure 0x%x\n", val);
2550#endif
2551 }
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302552 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002553 CAM_DBG(CAM_ISP, "CSID RDI EOF received");
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302554
Jing Zhouff57d862017-03-21 00:54:25 -07002555 if (irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF)
2556 complete(&csid_hw->csid_rdin_complete[i]);
2557
2558 if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002559 CAM_ERR(CAM_ISP, "CSID:%d RDI fifo over flow",
Jing Zhouff57d862017-03-21 00:54:25 -07002560 csid_hw->hw_intf->hw_idx);
2561 /*Stop RDI path immediately */
2562 cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
2563 soc_info->reg_map[0].mem_base +
2564 csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
2565 }
2566 }
2567
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002568 CAM_DBG(CAM_ISP, "IRQ Handling exit");
Jing Zhouff57d862017-03-21 00:54:25 -07002569 return IRQ_HANDLED;
2570}
2571
2572int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
2573 uint32_t csid_idx)
2574{
2575 int rc = -EINVAL;
2576 uint32_t i;
2577 struct cam_ife_csid_path_cfg *path_data;
2578 struct cam_ife_csid_cid_data *cid_data;
2579 struct cam_hw_info *csid_hw_info;
2580 struct cam_ife_csid_hw *ife_csid_hw = NULL;
2581
2582 if (csid_idx >= CAM_IFE_CSID_HW_RES_MAX) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002583 CAM_ERR(CAM_ISP, "Invalid csid index:%d", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002584 return rc;
2585 }
2586
2587 csid_hw_info = (struct cam_hw_info *) csid_hw_intf->hw_priv;
2588 ife_csid_hw = (struct cam_ife_csid_hw *) csid_hw_info->core_info;
2589
2590 ife_csid_hw->hw_intf = csid_hw_intf;
2591 ife_csid_hw->hw_info = csid_hw_info;
2592
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002593 CAM_DBG(CAM_ISP, "type %d index %d",
Jing Zhouff57d862017-03-21 00:54:25 -07002594 ife_csid_hw->hw_intf->hw_type, csid_idx);
2595
2596
2597 ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
2598 mutex_init(&ife_csid_hw->hw_info->hw_mutex);
2599 spin_lock_init(&ife_csid_hw->hw_info->hw_lock);
2600 init_completion(&ife_csid_hw->hw_info->hw_complete);
2601
2602 init_completion(&ife_csid_hw->csid_top_complete);
2603 init_completion(&ife_csid_hw->csid_csi2_complete);
2604 init_completion(&ife_csid_hw->csid_ipp_complete);
2605 for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
2606 init_completion(&ife_csid_hw->csid_rdin_complete[i]);
2607
2608
2609 rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
2610 cam_ife_csid_irq, ife_csid_hw);
2611 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002612 CAM_ERR(CAM_ISP, "CSID:%d Failed to init_soc", csid_idx);
Jing Zhouff57d862017-03-21 00:54:25 -07002613 goto err;
2614 }
2615
2616 ife_csid_hw->hw_intf->hw_ops.get_hw_caps = cam_ife_csid_get_hw_caps;
2617 ife_csid_hw->hw_intf->hw_ops.init = cam_ife_csid_init_hw;
2618 ife_csid_hw->hw_intf->hw_ops.deinit = cam_ife_csid_deinit_hw;
2619 ife_csid_hw->hw_intf->hw_ops.reset = cam_ife_csid_reset;
2620 ife_csid_hw->hw_intf->hw_ops.reserve = cam_ife_csid_reserve;
2621 ife_csid_hw->hw_intf->hw_ops.release = cam_ife_csid_release;
2622 ife_csid_hw->hw_intf->hw_ops.start = cam_ife_csid_start;
2623 ife_csid_hw->hw_intf->hw_ops.stop = cam_ife_csid_stop;
2624 ife_csid_hw->hw_intf->hw_ops.read = cam_ife_csid_read;
2625 ife_csid_hw->hw_intf->hw_ops.write = cam_ife_csid_write;
2626 ife_csid_hw->hw_intf->hw_ops.process_cmd = cam_ife_csid_process_cmd;
2627
2628 /*Initialize the CID resoure */
2629 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
2630 ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;
2631 ife_csid_hw->cid_res[i].res_id = i;
2632 ife_csid_hw->cid_res[i].res_state =
2633 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2634 ife_csid_hw->cid_res[i].hw_intf = ife_csid_hw->hw_intf;
2635
2636 cid_data = kzalloc(sizeof(struct cam_ife_csid_cid_data),
2637 GFP_KERNEL);
2638 if (!cid_data) {
2639 rc = -ENOMEM;
2640 goto err;
2641 }
2642 ife_csid_hw->cid_res[i].res_priv = cid_data;
2643 }
2644
2645 /* Initialize the IPP resources */
2646 if (ife_csid_hw->csid_info->csid_reg->cmn_reg->no_pix) {
2647 ife_csid_hw->ipp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
2648 ife_csid_hw->ipp_res.res_id = CAM_IFE_PIX_PATH_RES_IPP;
2649 ife_csid_hw->ipp_res.res_state =
2650 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2651 ife_csid_hw->ipp_res.hw_intf = ife_csid_hw->hw_intf;
2652 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2653 GFP_KERNEL);
2654 if (!path_data) {
2655 rc = -ENOMEM;
2656 goto err;
2657 }
2658 ife_csid_hw->ipp_res.res_priv = path_data;
2659 }
2660
2661 /* Initialize the RDI resource */
2662 for (i = 0; i < ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2663 i++) {
2664 /* res type is from RDI 0 to RDI3 */
2665 ife_csid_hw->rdi_res[i].res_type =
2666 CAM_ISP_RESOURCE_PIX_PATH;
2667 ife_csid_hw->rdi_res[i].res_id = i;
2668 ife_csid_hw->rdi_res[i].res_state =
2669 CAM_ISP_RESOURCE_STATE_AVAILABLE;
2670 ife_csid_hw->rdi_res[i].hw_intf = ife_csid_hw->hw_intf;
2671
2672 path_data = kzalloc(sizeof(struct cam_ife_csid_path_cfg),
2673 GFP_KERNEL);
2674 if (!path_data) {
2675 rc = -ENOMEM;
2676 goto err;
2677 }
2678 ife_csid_hw->rdi_res[i].res_priv = path_data;
2679 }
2680
2681 return 0;
2682err:
2683 if (rc) {
2684 kfree(ife_csid_hw->ipp_res.res_priv);
2685 for (i = 0; i <
2686 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis; i++)
2687 kfree(ife_csid_hw->rdi_res[i].res_priv);
2688
2689 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2690 kfree(ife_csid_hw->cid_res[i].res_priv);
2691
2692 }
2693
2694 return rc;
2695}
2696
2697
2698int cam_ife_csid_hw_deinit(struct cam_ife_csid_hw *ife_csid_hw)
2699{
2700 int rc = -EINVAL;
2701 uint32_t i;
2702
2703 if (!ife_csid_hw) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002704 CAM_ERR(CAM_ISP, "Invalid param");
Jing Zhouff57d862017-03-21 00:54:25 -07002705 return rc;
2706 }
2707
2708 /* release the privdate data memory from resources */
2709 kfree(ife_csid_hw->ipp_res.res_priv);
2710 for (i = 0; i <
2711 ife_csid_hw->csid_info->csid_reg->cmn_reg->no_rdis;
2712 i++) {
2713 kfree(ife_csid_hw->rdi_res[i].res_priv);
2714 }
2715 for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++)
2716 kfree(ife_csid_hw->cid_res[i].res_priv);
2717
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302718 cam_ife_csid_deinit_soc_resources(&ife_csid_hw->hw_info->soc_info);
Jing Zhouff57d862017-03-21 00:54:25 -07002719
2720 return 0;
2721}