blob: b1aaafba8514e34d780b8c783cdb4f1a001f558e [file] [log] [blame]
Harsh Shaha1af8822017-05-11 22:06:36 -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
Harsh Shaha1af8822017-05-11 22:06:36 -070013#include <linux/ratelimit.h>
14#include <linux/slab.h>
15#include "cam_io_util.h"
16#include "cam_cdm_util.h"
17#include "cam_hw_intf.h"
Harsh Shah19f55812017-06-26 18:58:49 -070018#include "cam_ife_hw_mgr.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070019#include "cam_vfe_hw_intf.h"
20#include "cam_irq_controller.h"
Harsh Shah19f55812017-06-26 18:58:49 -070021#include "cam_tasklet_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070022#include "cam_vfe_bus.h"
23#include "cam_vfe_bus_ver2.h"
24#include "cam_vfe_core.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070025#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070026
Harsh Shah19f55812017-06-26 18:58:49 -070027static const char drv_name[] = "vfe_bus";
28
29#define CAM_VFE_BUS_IRQ_REG0 0
30#define CAM_VFE_BUS_IRQ_REG1 1
31#define CAM_VFE_BUS_IRQ_REG2 2
32#define CAM_VFE_BUS_IRQ_MAX 3
33
34#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
Harsh Shah23557ae2017-05-13 18:14:34 -070035
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +053036#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
37#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
38
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -070039#define ALIGNUP(value, alignment) \
40 ((value + alignment - 1) / alignment * alignment)
41
Junzhe Zou193d78c2017-05-16 15:10:54 -070042#define MAX_BUF_UPDATE_REG_NUM \
43 (sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070044#define MAX_REG_VAL_PAIR_SIZE \
Harsh Shah19f55812017-06-26 18:58:49 -070045 (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070046
47#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
Harsh Shah19f55812017-06-26 18:58:49 -070048 do { \
49 buf_array[index++] = offset; \
50 buf_array[index++] = val; \
51 } while (0)
Harsh Shaha1af8822017-05-11 22:06:36 -070052
53enum cam_vfe_bus_packer_format {
54 PACKER_FMT_PLAIN_128 = 0x0,
55 PACKER_FMT_PLAIN_8 = 0x1,
56 PACKER_FMT_PLAIN_16_10BPP = 0x2,
57 PACKER_FMT_PLAIN_16_12BPP = 0x3,
58 PACKER_FMT_PLAIN_16_14BPP = 0x4,
59 PACKER_FMT_PLAIN_16_16BPP = 0x5,
60 PACKER_FMT_ARGB_10 = 0x6,
61 PACKER_FMT_ARGB_12 = 0x7,
62 PACKER_FMT_ARGB_14 = 0x8,
63 PACKER_FMT_PLAIN_32_20BPP = 0x9,
64 PACKER_FMT_PLAIN_64 = 0xA,
65 PACKER_FMT_TP_10 = 0xB,
66 PACKER_FMT_PLAIN_32_32BPP = 0xC,
67 PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
68 PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
69 PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
70 PACKER_FMT_MAX = 0xF,
71};
72
73struct cam_vfe_bus_ver2_common_data {
Harsh Shah19f55812017-06-26 18:58:49 -070074 uint32_t core_index;
Harsh Shaha1af8822017-05-11 22:06:36 -070075 void __iomem *mem_base;
76 struct cam_hw_intf *hw_intf;
77 void *bus_irq_controller;
78 void *vfe_irq_controller;
79 struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070080 uint32_t io_buf_update[
Harsh Shah19f55812017-06-26 18:58:49 -070081 MAX_REG_VAL_PAIR_SIZE];
82
83 struct cam_vfe_bus_irq_evt_payload evt_payload[
84 CAM_VFE_BUS_VER2_PAYLOAD_MAX];
85 struct list_head free_payload_list;
Harsh Shaha1af8822017-05-11 22:06:36 -070086};
87
88struct cam_vfe_bus_ver2_wm_resource_data {
89 uint32_t index;
90 struct cam_vfe_bus_ver2_common_data *common_data;
91 struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
Harsh Shah19f55812017-06-26 18:58:49 -070092 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -070093
94 uint32_t irq_enabled;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -070095 bool init_cfg_done;
96 bool hfr_cfg_done;
Harsh Shah19f55812017-06-26 18:58:49 -070097
Harsh Shaha1af8822017-05-11 22:06:36 -070098 uint32_t offset;
99 uint32_t width;
100 uint32_t height;
101 uint32_t stride;
102 uint32_t format;
103 enum cam_vfe_bus_packer_format pack_fmt;
104
105 uint32_t burst_len;
106 uint32_t frame_based;
107
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700108 uint32_t en_ubwc;
109 uint32_t packer_cfg;
110 uint32_t tile_cfg;
111 uint32_t h_init;
112 uint32_t v_init;
113 uint32_t ubwc_meta_stride;
114 uint32_t ubwc_mode_cfg;
115 uint32_t ubwc_meta_offset;
116
Harsh Shaha1af8822017-05-11 22:06:36 -0700117 uint32_t irq_subsample_period;
118 uint32_t irq_subsample_pattern;
119 uint32_t framedrop_period;
120 uint32_t framedrop_pattern;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700121
122 uint32_t en_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -0700123};
124
125struct cam_vfe_bus_ver2_comp_grp_data {
126 enum cam_vfe_bus_ver2_comp_grp_type comp_grp_type;
127 struct cam_vfe_bus_ver2_common_data *common_data;
128 struct cam_vfe_bus_ver2_reg_offset_comp_grp *hw_regs;
129
130 uint32_t irq_enabled;
131 uint32_t comp_grp_local_idx;
132 uint32_t unique_id;
133
134 uint32_t is_master;
135 uint32_t dual_slave_core;
136 uint32_t intra_client_mask;
137 uint32_t composite_mask;
Harsh Shah19f55812017-06-26 18:58:49 -0700138
139 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700140};
141
142struct cam_vfe_bus_ver2_vfe_out_data {
143 uint32_t out_type;
144 struct cam_vfe_bus_ver2_common_data *common_data;
145
146 uint32_t num_wm;
147 struct cam_isp_resource_node *wm_res[PLANE_MAX];
148
149 struct cam_isp_resource_node *comp_grp;
150 enum cam_isp_hw_sync_mode dual_comp_sync_mode;
151 uint32_t dual_hw_alternate_vfe_id;
152 struct list_head vfe_out_list;
153
154 uint32_t format;
155 uint32_t max_width;
156 uint32_t max_height;
157 struct cam_cdm_utils_ops *cdm_util_ops;
158};
159
Harsh Shaha1af8822017-05-11 22:06:36 -0700160struct cam_vfe_bus_ver2_priv {
161 struct cam_vfe_bus_ver2_common_data common_data;
162
163 struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
164 struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
165 struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
166
167 struct list_head free_comp_grp;
168 struct list_head free_dual_comp_grp;
169 struct list_head used_comp_grp;
170
Harsh Shah19f55812017-06-26 18:58:49 -0700171 uint32_t irq_handle;
Harsh Shaha1af8822017-05-11 22:06:36 -0700172};
173
Harsh Shah19f55812017-06-26 18:58:49 -0700174static int cam_vfe_bus_get_evt_payload(
175 struct cam_vfe_bus_ver2_common_data *common_data,
176 struct cam_vfe_bus_irq_evt_payload **evt_payload)
177{
178 if (list_empty(&common_data->free_payload_list)) {
179 *evt_payload = NULL;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700180 CAM_ERR(CAM_ISP, "No free payload");
Harsh Shah19f55812017-06-26 18:58:49 -0700181 return -ENODEV;
182 }
183
184 *evt_payload = list_first_entry(&common_data->free_payload_list,
185 struct cam_vfe_bus_irq_evt_payload, list);
186 list_del_init(&(*evt_payload)->list);
187 return 0;
188}
189
Harsh Shaha1af8822017-05-11 22:06:36 -0700190static int cam_vfe_bus_put_evt_payload(void *core_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700191 struct cam_vfe_bus_irq_evt_payload **evt_payload)
192{
193 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
194 uint32_t *ife_irq_regs = NULL;
195 uint32_t status_reg0, status_reg1, status_reg2;
196
197 if (!core_info) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700198 CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
Harsh Shah19f55812017-06-26 18:58:49 -0700199 return -EINVAL;
200 }
201 if (*evt_payload == NULL) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700202 CAM_ERR(CAM_ISP, "No payload to put");
Harsh Shah19f55812017-06-26 18:58:49 -0700203 return -EINVAL;
204 }
205
206 ife_irq_regs = (*evt_payload)->irq_reg_val;
207 status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
208 status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
209 status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
210
211 if (status_reg0 || status_reg1 || status_reg2) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700212 CAM_DBG(CAM_ISP, "status0 0x%x status1 0x%x status2 0x%x",
Harsh Shah19f55812017-06-26 18:58:49 -0700213 status_reg0, status_reg1, status_reg2);
214 return 0;
215 }
216
217 common_data = core_info;
218 list_add_tail(&(*evt_payload)->list,
219 &common_data->free_payload_list);
220 *evt_payload = NULL;
221
222 return 0;
223}
Harsh Shaha1af8822017-05-11 22:06:36 -0700224
225static int cam_vfe_bus_ver2_get_intra_client_mask(
226 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
227 enum cam_vfe_bus_ver2_vfe_core_id current_core,
228 uint32_t *intra_client_mask)
229{
230 int rc = 0;
231
232 *intra_client_mask = 0;
233
234 if (dual_slave_core == current_core) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700235 CAM_ERR(CAM_ISP,
236 "Invalid params. Same core as Master and Slave");
Harsh Shaha1af8822017-05-11 22:06:36 -0700237 return -EINVAL;
238 }
239
240 switch (current_core) {
241 case CAM_VFE_BUS_VER2_VFE_CORE_0:
242 switch (dual_slave_core) {
243 case CAM_VFE_BUS_VER2_VFE_CORE_1:
244 *intra_client_mask = 0x1;
245 break;
246 case CAM_VFE_BUS_VER2_VFE_CORE_2:
247 *intra_client_mask = 0x2;
248 break;
249 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700250 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700251 dual_slave_core);
252 rc = -EINVAL;
253 break;
254 }
255 break;
256 case CAM_VFE_BUS_VER2_VFE_CORE_1:
257 switch (dual_slave_core) {
258 case CAM_VFE_BUS_VER2_VFE_CORE_0:
259 *intra_client_mask = 0x1;
260 break;
261 case CAM_VFE_BUS_VER2_VFE_CORE_2:
262 *intra_client_mask = 0x2;
263 break;
264 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700265 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700266 dual_slave_core);
267 rc = -EINVAL;
268 break;
269 }
270 break;
271 case CAM_VFE_BUS_VER2_VFE_CORE_2:
272 switch (dual_slave_core) {
273 case CAM_VFE_BUS_VER2_VFE_CORE_0:
274 *intra_client_mask = 0x1;
275 break;
276 case CAM_VFE_BUS_VER2_VFE_CORE_1:
277 *intra_client_mask = 0x2;
278 break;
279 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700280 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700281 dual_slave_core);
282 rc = -EINVAL;
283 break;
284 }
285 break;
286 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700287 CAM_ERR(CAM_ISP,
288 "Invalid value for master core %u", current_core);
Harsh Shaha1af8822017-05-11 22:06:36 -0700289 rc = -EINVAL;
290 break;
291 }
292
293 return rc;
294}
295
296static enum cam_vfe_bus_ver2_vfe_out_type
297 cam_vfe_bus_get_out_res_id(uint32_t res_type)
298{
299 switch (res_type) {
300 case CAM_ISP_IFE_OUT_RES_FULL:
301 return CAM_VFE_BUS_VER2_VFE_OUT_FULL;
302 case CAM_ISP_IFE_OUT_RES_DS4:
303 return CAM_VFE_BUS_VER2_VFE_OUT_DS4;
304 case CAM_ISP_IFE_OUT_RES_DS16:
305 return CAM_VFE_BUS_VER2_VFE_OUT_DS16;
306 case CAM_ISP_IFE_OUT_RES_FD:
307 return CAM_VFE_BUS_VER2_VFE_OUT_FD;
308 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
309 return CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP;
310 case CAM_ISP_IFE_OUT_RES_PDAF:
311 return CAM_VFE_BUS_VER2_VFE_OUT_PDAF;
312 case CAM_ISP_IFE_OUT_RES_RDI_0:
313 return CAM_VFE_BUS_VER2_VFE_OUT_RDI0;
314 case CAM_ISP_IFE_OUT_RES_RDI_1:
315 return CAM_VFE_BUS_VER2_VFE_OUT_RDI1;
316 case CAM_ISP_IFE_OUT_RES_RDI_2:
317 return CAM_VFE_BUS_VER2_VFE_OUT_RDI2;
318 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
319 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE;
320 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
321 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST;
322 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
323 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG;
324 case CAM_ISP_IFE_OUT_RES_STATS_BF:
325 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF;
326 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
327 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG;
328 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
329 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST;
330 case CAM_ISP_IFE_OUT_RES_STATS_RS:
331 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS;
332 case CAM_ISP_IFE_OUT_RES_STATS_CS:
333 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS;
334 case CAM_ISP_IFE_OUT_RES_STATS_IHIST:
335 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST;
336 default:
337 return CAM_VFE_BUS_VER2_VFE_OUT_MAX;
338 }
339}
340
341static int cam_vfe_bus_get_num_wm(
342 enum cam_vfe_bus_ver2_vfe_out_type res_type,
343 uint32_t format)
344{
345 switch (res_type) {
346 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
347 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
348 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
349 switch (format) {
350 case CAM_FORMAT_MIPI_RAW_8:
351 case CAM_FORMAT_MIPI_RAW_10:
352 case CAM_FORMAT_MIPI_RAW_12:
353 case CAM_FORMAT_MIPI_RAW_14:
354 case CAM_FORMAT_MIPI_RAW_16:
355 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530356 case CAM_FORMAT_DPCM_10_6_10:
357 case CAM_FORMAT_DPCM_10_8_10:
358 case CAM_FORMAT_DPCM_12_6_12:
359 case CAM_FORMAT_DPCM_12_8_12:
360 case CAM_FORMAT_DPCM_14_8_14:
361 case CAM_FORMAT_DPCM_14_10_14:
362 case CAM_FORMAT_PLAIN8:
363 case CAM_FORMAT_PLAIN16_8:
364 case CAM_FORMAT_PLAIN16_10:
365 case CAM_FORMAT_PLAIN16_12:
366 case CAM_FORMAT_PLAIN16_14:
367 case CAM_FORMAT_PLAIN16_16:
368 case CAM_FORMAT_PLAIN32_20:
Harsh Shaha1af8822017-05-11 22:06:36 -0700369 case CAM_FORMAT_PLAIN128:
370 return 1;
371 default:
372 break;
373 }
374 break;
375 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
376 switch (format) {
377 case CAM_FORMAT_NV21:
378 case CAM_FORMAT_NV12:
379 case CAM_FORMAT_MIPI_RAW_8:
380 case CAM_FORMAT_PLAIN8:
381 case CAM_FORMAT_TP10:
382 case CAM_FORMAT_UBWC_NV12:
383 case CAM_FORMAT_UBWC_NV12_4R:
384 case CAM_FORMAT_UBWC_TP10:
385 case CAM_FORMAT_UBWC_P010:
386 return 2;
387 default:
388 break;
389 }
390 break;
391 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
392 switch (format) {
393 case CAM_FORMAT_NV21:
394 case CAM_FORMAT_NV12:
395 case CAM_FORMAT_PLAIN8:
396 case CAM_FORMAT_TP10:
397 case CAM_FORMAT_PLAIN16_10:
398 return 2;
399 default:
400 break;
401 }
402 break;
403 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
404 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
405 switch (format) {
406 case CAM_FORMAT_PD8:
407 case CAM_FORMAT_PD10:
408 return 1;
409 default:
410 break;
411 }
412 break;
413 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
414 switch (format) {
415 case CAM_FORMAT_ARGB_14:
416 case CAM_FORMAT_PLAIN8:
417 case CAM_FORMAT_PLAIN16_10:
418 case CAM_FORMAT_PLAIN16_12:
419 case CAM_FORMAT_PLAIN16_14:
420 return 1;
421 default:
422 break;
423 }
424 break;
425 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
426 switch (format) {
427 case CAM_FORMAT_PLAIN8:
428 case CAM_FORMAT_PLAIN16_10:
429 case CAM_FORMAT_PLAIN16_12:
430 case CAM_FORMAT_PLAIN16_14:
431 return 1;
432 default:
433 break;
434 }
435 break;
436 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
437 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
438 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
439 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
440 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
441 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
442 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
443 switch (format) {
444 case CAM_FORMAT_PLAIN64:
445 return 1;
446 default:
447 break;
448 }
449 break;
450 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
451 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
452 switch (format) {
453 case CAM_FORMAT_PLAIN16_16:
454 return 1;
455 default:
456 break;
457 }
458 break;
459 default:
460 break;
461 }
462
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700463 CAM_ERR(CAM_ISP, "Unsupported format %u for resource_type %u",
464 format, res_type);
Harsh Shaha1af8822017-05-11 22:06:36 -0700465
466 return -EINVAL;
467}
468
469static int cam_vfe_bus_get_wm_idx(
470 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
471 enum cam_vfe_bus_plane_type plane)
472{
473 int wm_idx = -1;
474
475 switch (vfe_out_res_id) {
476 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
477 switch (plane) {
478 case PLANE_Y:
479 wm_idx = 3;
480 break;
481 case PLANE_C:
482 wm_idx = 4;
483 break;
484 default:
485 break;
486 }
487 break;
488 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
489 switch (plane) {
490 case PLANE_Y:
491 wm_idx = 5;
492 break;
493 default:
494 break;
495 }
496 break;
497 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
498 switch (plane) {
499 case PLANE_Y:
500 wm_idx = 6;
501 break;
502 default:
503 break;
504 }
505 break;
506 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
507 switch (plane) {
508 case PLANE_Y:
509 wm_idx = 7;
510 break;
511 case PLANE_C:
512 wm_idx = 8;
513 break;
514 default:
515 break;
516 }
517 break;
518 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
519 switch (plane) {
520 case PLANE_Y:
521 wm_idx = 9;
522 break;
523 default:
524 break;
525 }
526 break;
527 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
528 switch (plane) {
529 case PLANE_Y:
530 wm_idx = 10;
531 break;
532 default:
533 break;
534 }
535 break;
536 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
537 switch (plane) {
538 case PLANE_Y:
539 wm_idx = 0;
540 break;
541 default:
542 break;
543 }
544 break;
545 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
546 switch (plane) {
547 case PLANE_Y:
548 wm_idx = 1;
549 break;
550 default:
551 break;
552 }
553 break;
554 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
555 switch (plane) {
556 case PLANE_Y:
557 wm_idx = 2;
558 break;
559 default:
560 break;
561 }
562 break;
563 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
564 switch (plane) {
565 case PLANE_Y:
566 wm_idx = 11;
567 break;
568 default:
569 break;
570 }
571 break;
572 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
573 switch (plane) {
574 case PLANE_Y:
575 wm_idx = 12;
576 break;
577 default:
578 break;
579 }
580 break;
581 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
582 switch (plane) {
583 case PLANE_Y:
584 wm_idx = 13;
585 break;
586 default:
587 break;
588 }
589 break;
590 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
591 switch (plane) {
592 case PLANE_Y:
593 wm_idx = 14;
594 break;
595 default:
596 break;
597 }
598 break;
599 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
600 switch (plane) {
601 case PLANE_Y:
602 wm_idx = 15;
603 break;
604 default:
605 break;
606 }
607 break;
608 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
609 switch (plane) {
610 case PLANE_Y:
611 wm_idx = 16;
612 break;
613 default:
614 break;
615 }
616 break;
617 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
618 switch (plane) {
619 case PLANE_Y:
620 wm_idx = 17;
621 break;
622 default:
623 break;
624 }
625 break;
626 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
627 switch (plane) {
628 case PLANE_Y:
629 wm_idx = 18;
630 break;
631 default:
632 break;
633 }
634 break;
635 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
636 switch (plane) {
637 case PLANE_Y:
638 wm_idx = 19;
639 break;
640 default:
641 break;
642 }
643 break;
644 default:
645 break;
646 }
647
648 return wm_idx;
649}
650
651static enum cam_vfe_bus_packer_format
652 cam_vfe_bus_get_packer_fmt(uint32_t out_fmt)
653{
654 switch (out_fmt) {
655 case CAM_FORMAT_NV21:
656 case CAM_FORMAT_NV12:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700657 case CAM_FORMAT_UBWC_NV12:
658 case CAM_FORMAT_UBWC_NV12_4R:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530659 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530660 case CAM_FORMAT_PLAIN64:
661 return PACKER_FMT_PLAIN_64;
662 case CAM_FORMAT_MIPI_RAW_6:
663 case CAM_FORMAT_MIPI_RAW_8:
664 case CAM_FORMAT_MIPI_RAW_10:
665 case CAM_FORMAT_MIPI_RAW_12:
666 case CAM_FORMAT_MIPI_RAW_14:
667 case CAM_FORMAT_MIPI_RAW_16:
668 case CAM_FORMAT_MIPI_RAW_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530669 case CAM_FORMAT_PLAIN128:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530670 case CAM_FORMAT_PLAIN8:
671 case CAM_FORMAT_PLAIN16_8:
672 case CAM_FORMAT_PLAIN16_10:
673 case CAM_FORMAT_PLAIN16_12:
674 case CAM_FORMAT_PLAIN16_14:
675 case CAM_FORMAT_PLAIN16_16:
676 case CAM_FORMAT_PLAIN32_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530677 case CAM_FORMAT_PD8:
678 case CAM_FORMAT_PD10:
679 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700680 case CAM_FORMAT_UBWC_TP10:
681 case CAM_FORMAT_TP10:
682 return PACKER_FMT_TP_10;
Harsh Shaha1af8822017-05-11 22:06:36 -0700683 default:
684 return PACKER_FMT_MAX;
685 }
686}
687
688static int cam_vfe_bus_acquire_wm(
689 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
690 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700691 void *tasklet,
692 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700693 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
694 enum cam_vfe_bus_plane_type plane,
695 enum cam_isp_hw_split_id split_id,
696 uint32_t subscribe_irq,
697 struct cam_isp_resource_node **wm_res,
698 uint32_t *client_done_mask)
699{
700 uint32_t wm_idx = 0;
701 struct cam_isp_resource_node *wm_res_local = NULL;
702 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
703
704 *wm_res = NULL;
705 *client_done_mask = 0;
706
707 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
708 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
709 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700710 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700711 vfe_out_res_id, plane);
712 return -EINVAL;
713 }
714
715 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700716 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700717 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
718
719 rsrc_data = wm_res_local->res_priv;
720 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700721 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700722 rsrc_data->format = out_port_info->format;
723 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
724
725 rsrc_data->width = out_port_info->width;
726 rsrc_data->height = out_port_info->height;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700727
728 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700729 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530730 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
731 rsrc_data->height = 0;
732 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
733 rsrc_data->pack_fmt = 0x0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700734 rsrc_data->en_cfg = 0x3;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530735 } else if (rsrc_data->index < 5 ||
736 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700737 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
738 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700739 case CAM_FORMAT_UBWC_NV12_4R:
740 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700741 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
742 switch (plane) {
743 case PLANE_C:
744 rsrc_data->height /= 2;
745 break;
746 case PLANE_Y:
747 break;
748 default:
749 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
750 return -EINVAL;
751 }
752 break;
753 case CAM_FORMAT_UBWC_NV12:
754 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700755 /* Fall through for NV12 */
756 case CAM_FORMAT_NV21:
757 case CAM_FORMAT_NV12:
758 switch (plane) {
759 case PLANE_C:
760 rsrc_data->height /= 2;
761 break;
762 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700763 break;
764 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700765 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
766 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700767 }
768 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700769 case CAM_FORMAT_UBWC_TP10:
770 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700771 rsrc_data->width =
772 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
773 switch (plane) {
774 case PLANE_C:
775 rsrc_data->height /= 2;
776 break;
777 case PLANE_Y:
778 break;
779 default:
780 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
781 return -EINVAL;
782 }
783 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700784 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700785 rsrc_data->width =
786 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700787 switch (plane) {
788 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700789 rsrc_data->height /= 2;
790 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700791 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700792 break;
793 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700794 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
795 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700796 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700797 break;
798 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700799 CAM_ERR(CAM_ISP, "Invalid format %d\n",
800 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700801 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700802 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700803 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530804 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700805 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530806 rsrc_data->width = 0;
807 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530808 rsrc_data->stride = 1;
809 rsrc_data->en_cfg = 0x3;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700810 } else {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700811 /* Write master 5-6 DS ports , 9 - Raw dump , 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700812 rsrc_data->width = rsrc_data->width * 4;
813 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700814 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700815 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700816 if (vfe_out_res_id >= CAM_ISP_IFE_OUT_RES_RDI_0 &&
817 vfe_out_res_id <= CAM_ISP_IFE_OUT_RES_RDI_3)
818 rsrc_data->frame_based = 1;
819
820 *client_done_mask = (1 << wm_idx);
821 *wm_res = wm_res_local;
822
823 return 0;
824}
825
826static int cam_vfe_bus_release_wm(void *bus_priv,
827 struct cam_isp_resource_node *wm_res)
828{
829 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
830 wm_res->res_priv;
831
832 rsrc_data->irq_enabled = 0;
833 rsrc_data->offset = 0;
834 rsrc_data->width = 0;
835 rsrc_data->height = 0;
836 rsrc_data->stride = 0;
837 rsrc_data->format = 0;
838 rsrc_data->pack_fmt = 0;
839 rsrc_data->burst_len = 0;
840 rsrc_data->frame_based = 0;
841 rsrc_data->irq_subsample_period = 0;
842 rsrc_data->irq_subsample_pattern = 0;
843 rsrc_data->framedrop_period = 0;
844 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700845 rsrc_data->packer_cfg = 0;
846 rsrc_data->en_ubwc = 0;
847 rsrc_data->tile_cfg = 0;
848 rsrc_data->h_init = 0;
849 rsrc_data->v_init = 0;
850 rsrc_data->ubwc_meta_stride = 0;
851 rsrc_data->ubwc_mode_cfg = 0;
852 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700853 rsrc_data->init_cfg_done = false;
854 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700855 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700856
857 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700858 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
859
860 return 0;
861}
862
863static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
864{
865 int rc = 0;
866 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
867 wm_res->res_priv;
868 struct cam_vfe_bus_ver2_common_data *common_data =
869 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -0700870 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -0700871
Harsh Shah23557ae2017-05-13 18:14:34 -0700872 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
873 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -0700874 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
875
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700876 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -0700877 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700878 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -0700879 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700880 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -0700881 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700882
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530883 /* Configure stride for RDIs */
884 if (rsrc_data->index < 3)
885 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
886 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -0700887
Harsh Shah19f55812017-06-26 18:58:49 -0700888 /* Subscribe IRQ */
889 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700890 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -0700891 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
892 (1 << rsrc_data->index);
893 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
894 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
895 bus_irq_reg_mask, wm_res,
896 wm_res->top_half_handler,
897 cam_ife_mgr_do_tasklet_buf_done,
898 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
899 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700900 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -0700901 rsrc_data->index);
902 return -EFAULT;
903 }
904 }
905
Junzhe Zou3d292562017-07-12 17:59:58 -0700906 /* enable ubwc if needed*/
907 if (rsrc_data->en_ubwc) {
908 cam_io_w_mb(0x1, common_data->mem_base +
909 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
910 }
911
Harsh Shah19f55812017-06-26 18:58:49 -0700912 /* Enable WM */
913 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
914 rsrc_data->hw_regs->cfg);
915
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700916 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700917 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700918 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700919 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700920 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700921 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700922 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
923 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
924 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700925
926 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
927
928 return rc;
929}
930
931static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
932{
933 int rc = 0;
934 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
935 wm_res->res_priv;
936 struct cam_vfe_bus_ver2_common_data *common_data =
937 rsrc_data->common_data;
938
939 /* Disble WM */
940 cam_io_w_mb(0x0,
941 common_data->mem_base + rsrc_data->hw_regs->cfg);
942
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700943 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -0700944 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -0700945 if (rsrc_data->irq_enabled)
946 rc = cam_irq_controller_unsubscribe_irq(
947 common_data->bus_irq_controller,
948 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -0700949
950 /* Halt & Reset WM */
951 cam_io_w_mb(BIT(rsrc_data->index),
952 common_data->mem_base + common_data->common_reg->sw_reset);
953
954 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
955
956 return rc;
957}
958
959static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
960 struct cam_irq_th_payload *th_payload)
961{
Harsh Shah19f55812017-06-26 18:58:49 -0700962 int32_t rc;
963 int i;
964 struct cam_isp_resource_node *wm_res = NULL;
965 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
966 struct cam_vfe_bus_irq_evt_payload *evt_payload;
967
968 wm_res = th_payload->handler_priv;
969 if (!wm_res) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700970 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700971 return -ENODEV;
972 }
973
974 rsrc_data = wm_res->res_priv;
975
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700976 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
977 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -0700978
979 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
980 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700981 CAM_ERR_RATE_LIMIT(CAM_ISP,
982 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700983 return rc;
984 }
985
986 cam_isp_hw_get_timestamp(&evt_payload->ts);
987
988 evt_payload->ctx = rsrc_data->ctx;
989 evt_payload->core_index = rsrc_data->common_data->core_index;
990 evt_payload->evt_id = evt_id;
991
992 for (i = 0; i < th_payload->num_registers; i++)
993 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
994
995 th_payload->evt_payload_priv = evt_payload;
996
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700997 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -0700998 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -0700999}
1000
1001static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1002 void *evt_payload_priv)
1003{
1004 int rc = CAM_VFE_IRQ_STATUS_ERR;
1005 struct cam_isp_resource_node *wm_res = wm_node;
1006 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001007 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1008 (wm_res == NULL) ? NULL : wm_res->res_priv;
1009 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001010 uint32_t status_reg;
1011
Harsh Shah23557ae2017-05-13 18:14:34 -07001012 if (!evt_payload || !rsrc_data)
1013 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001014
Harsh Shah23557ae2017-05-13 18:14:34 -07001015 cam_ife_irq_regs = evt_payload->irq_reg_val;
1016 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1017
1018 if (status_reg & BIT(rsrc_data->index)) {
1019 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1020 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001021 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001022 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001023 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001024
1025 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001026 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001027 &evt_payload);
1028
1029 return rc;
1030}
1031
1032static int cam_vfe_bus_init_wm_resource(uint32_t index,
1033 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1034 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1035 struct cam_isp_resource_node *wm_res)
1036{
Harsh Shaha1af8822017-05-11 22:06:36 -07001037 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1038
1039 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1040 GFP_KERNEL);
1041 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001042 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001043 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001044 }
1045 wm_res->res_priv = rsrc_data;
1046
1047 rsrc_data->index = index;
1048 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1049 rsrc_data->common_data = &ver2_bus_priv->common_data;
1050
1051 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1052 INIT_LIST_HEAD(&wm_res->list);
1053
1054 wm_res->start = cam_vfe_bus_start_wm;
1055 wm_res->stop = cam_vfe_bus_stop_wm;
1056 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1057 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1058 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1059
Harsh Shah545df9a2017-06-16 16:43:17 -07001060 return 0;
1061}
1062
1063static int cam_vfe_bus_deinit_wm_resource(
1064 struct cam_isp_resource_node *wm_res)
1065{
1066 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1067
1068 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1069 INIT_LIST_HEAD(&wm_res->list);
1070
1071 wm_res->start = NULL;
1072 wm_res->stop = NULL;
1073 wm_res->top_half_handler = NULL;
1074 wm_res->bottom_half_handler = NULL;
1075 wm_res->hw_intf = NULL;
1076
1077 rsrc_data = wm_res->res_priv;
1078 wm_res->res_priv = NULL;
1079 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001080 CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001081 return -ENOMEM;
1082 }
1083 kfree(rsrc_data);
1084
1085 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001086}
1087
1088static void cam_vfe_bus_add_wm_to_comp_grp(
1089 struct cam_isp_resource_node *comp_grp,
1090 uint32_t composite_mask)
1091{
1092 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1093
1094 rsrc_data->composite_mask |= composite_mask;
1095}
1096
1097static void cam_vfe_bus_match_comp_grp(
1098 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1099 struct cam_isp_resource_node **comp_grp,
1100 uint32_t comp_grp_local_idx,
1101 uint32_t unique_id)
1102{
1103 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1104 struct cam_isp_resource_node *comp_grp_local = NULL;
1105
1106 list_for_each_entry(comp_grp_local,
1107 &ver2_bus_priv->used_comp_grp, list) {
1108 rsrc_data = comp_grp_local->res_priv;
1109 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1110 rsrc_data->unique_id == unique_id) {
1111 /* Match found */
1112 *comp_grp = comp_grp_local;
1113 return;
1114 }
1115 }
1116
1117 *comp_grp = NULL;
1118}
1119
1120static int cam_vfe_bus_acquire_comp_grp(
1121 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1122 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001123 void *tasklet,
1124 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001125 uint32_t unique_id,
1126 uint32_t is_dual,
1127 uint32_t is_master,
1128 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1129 struct cam_isp_resource_node **comp_grp)
1130{
1131 int rc = 0;
1132 struct cam_isp_resource_node *comp_grp_local = NULL;
1133 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1134
1135 /* Check if matching comp_grp already acquired */
1136 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1137 out_port_info->comp_grp_id, unique_id);
1138
1139 if (!comp_grp_local) {
1140 /* First find a free group */
1141 if (is_dual) {
1142 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001143 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001144 return -ENODEV;
1145 }
1146 comp_grp_local = list_first_entry(
1147 &ver2_bus_priv->free_dual_comp_grp,
1148 struct cam_isp_resource_node, list);
1149 rsrc_data = comp_grp_local->res_priv;
1150 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1151 dual_slave_core,
1152 comp_grp_local->hw_intf->hw_idx,
1153 &rsrc_data->intra_client_mask);
1154 } else {
1155 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001156 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001157 return -ENODEV;
1158 }
1159 comp_grp_local = list_first_entry(
1160 &ver2_bus_priv->free_comp_grp,
1161 struct cam_isp_resource_node, list);
1162 rsrc_data = comp_grp_local->res_priv;
1163 }
1164
1165 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001166 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001167 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1168
1169 rsrc_data->is_master = is_master;
1170 rsrc_data->composite_mask = 0;
1171 rsrc_data->unique_id = unique_id;
1172 rsrc_data->comp_grp_local_idx = out_port_info->comp_grp_id;
1173
1174 list_add_tail(&comp_grp_local->list,
1175 &ver2_bus_priv->used_comp_grp);
1176
1177 } else {
1178 rsrc_data = comp_grp_local->res_priv;
1179 /* Do not support runtime change in composite mask */
1180 if (comp_grp_local->res_state ==
1181 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001182 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001183 comp_grp_local->res_state,
1184 rsrc_data->comp_grp_type);
1185 return -EBUSY;
1186 }
1187 }
1188
Harsh Shah19f55812017-06-26 18:58:49 -07001189 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -07001190 *comp_grp = comp_grp_local;
1191
1192 return rc;
1193}
1194
1195static int cam_vfe_bus_release_comp_grp(
1196 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1197 struct cam_isp_resource_node *in_comp_grp)
1198{
1199 struct cam_isp_resource_node *comp_grp = NULL;
1200 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1201 int match_found = 0;
1202
1203 if (!in_comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001204 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_rsrc_data);
Harsh Shaha1af8822017-05-11 22:06:36 -07001205 return -EINVAL;
1206 }
1207
1208 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
1209 /* Already Released. Do Nothing */
1210 return 0;
1211 }
1212
1213 in_rsrc_data = in_comp_grp->res_priv;
1214
1215 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1216 if (comp_grp == in_comp_grp) {
1217 match_found = 1;
1218 break;
1219 }
1220 }
1221
1222 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001223 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001224 in_rsrc_data->comp_grp_type);
1225 return -ENODEV;
1226 }
1227
1228
1229 list_del(&comp_grp->list);
1230 if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1231 in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1232 list_add_tail(&comp_grp->list,
1233 &ver2_bus_priv->free_dual_comp_grp);
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001234 else if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1235 && in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
Harsh Shaha1af8822017-05-11 22:06:36 -07001236 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1237
Harsh Shaha1af8822017-05-11 22:06:36 -07001238 in_rsrc_data->unique_id = 0;
1239 in_rsrc_data->comp_grp_local_idx = 0;
1240 in_rsrc_data->composite_mask = 0;
1241 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1242
Harsh Shah19f55812017-06-26 18:58:49 -07001243 comp_grp->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001244 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1245
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001246 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001247}
1248
1249static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1250{
1251 int rc = 0;
1252 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1253 comp_grp->res_priv;
1254 struct cam_vfe_bus_ver2_common_data *common_data =
1255 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001256 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001257
1258 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1259 rsrc_data->hw_regs->comp_mask);
1260
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001261 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1262 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1263 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001264
1265 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1266 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1267 rsrc_data->is_master) {
1268 int dual_comp_grp = (rsrc_data->comp_grp_type -
1269 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1270 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1271 common_data->common_reg->dual_master_comp_cfg);
1272
1273 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1274 intra_client_en |=
1275 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1276
1277 cam_io_w_mb(intra_client_en, common_data->mem_base +
1278 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001279
1280 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1281 } else {
1282 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1283 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1284 (1 << (rsrc_data->comp_grp_type + 5));
1285 }
1286
1287 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001288 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001289 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1290 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1291 bus_irq_reg_mask, comp_grp,
1292 comp_grp->top_half_handler,
1293 cam_ife_mgr_do_tasklet_buf_done,
1294 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1295 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001296 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001297 rsrc_data->comp_grp_type);
1298 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001299 }
1300
1301 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001302
Harsh Shaha1af8822017-05-11 22:06:36 -07001303 return rc;
1304}
1305
1306static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1307{
1308 int rc = 0;
1309 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1310 comp_grp->res_priv;
1311 struct cam_vfe_bus_ver2_common_data *common_data =
1312 rsrc_data->common_data;
1313
1314 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001315 rc = cam_irq_controller_unsubscribe_irq(
1316 common_data->bus_irq_controller,
1317 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001318
1319 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1320 rsrc_data->hw_regs->comp_mask);
1321 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1322 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1323 rsrc_data->is_master) {
1324 int dual_comp_grp = (rsrc_data->comp_grp_type -
1325 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1326 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1327 common_data->common_reg->dual_master_comp_cfg);
1328
1329 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1330 intra_client_en &=
1331 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1332
1333 cam_io_w_mb(intra_client_en, common_data->mem_base +
1334 common_data->common_reg->dual_master_comp_cfg);
1335 }
1336
1337 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1338
1339 return rc;
1340}
1341
1342static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1343 struct cam_irq_th_payload *th_payload)
1344{
Harsh Shah19f55812017-06-26 18:58:49 -07001345 int32_t rc;
1346 int i;
1347 struct cam_isp_resource_node *comp_grp = NULL;
1348 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1349 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1350
1351 comp_grp = th_payload->handler_priv;
1352 if (!comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001353 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001354 return -ENODEV;
1355 }
1356
1357 rsrc_data = comp_grp->res_priv;
1358
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001359 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1360 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001361
1362 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1363 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001364 CAM_ERR_RATE_LIMIT(CAM_ISP,
1365 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001366 return rc;
1367 }
1368
1369 cam_isp_hw_get_timestamp(&evt_payload->ts);
1370
1371 evt_payload->ctx = rsrc_data->ctx;
1372 evt_payload->core_index = rsrc_data->common_data->core_index;
1373 evt_payload->evt_id = evt_id;
1374
1375 for (i = 0; i < th_payload->num_registers; i++)
1376 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1377
1378 th_payload->evt_payload_priv = evt_payload;
1379
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001380 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001381 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001382}
1383
1384static int cam_vfe_bus_handle_comp_done_bottom_half(
1385 void *handler_priv,
1386 void *evt_payload_priv)
1387{
1388 int rc = CAM_VFE_IRQ_STATUS_ERR;
1389 struct cam_isp_resource_node *comp_grp = handler_priv;
1390 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1391 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001392 uint32_t *cam_ife_irq_regs;
1393 uint32_t status_reg;
1394 uint32_t comp_err_reg;
1395 uint32_t comp_grp_id;
1396
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001397 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001398
Harsh Shah23557ae2017-05-13 18:14:34 -07001399 if (!evt_payload)
1400 return rc;
1401
1402 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001403
Harsh Shaha1af8822017-05-11 22:06:36 -07001404 switch (rsrc_data->comp_grp_type) {
1405 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1406 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1407 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1408 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1409 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1410 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001411 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001412 CAM_VFE_BUS_VER2_COMP_GRP_0);
1413
1414 /* Check for Regular composite error */
1415 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1416
1417 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1418 if ((status_reg & BIT(11)) &&
1419 (comp_err_reg & rsrc_data->composite_mask)) {
1420 /* Check for Regular composite error */
1421 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1422 break;
1423 }
1424
1425 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1426 /* Check for Regular composite Overwrite */
1427 if ((status_reg & BIT(12)) &&
1428 (comp_err_reg & rsrc_data->composite_mask)) {
1429 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1430 break;
1431 }
1432
Harsh Shah23557ae2017-05-13 18:14:34 -07001433 /* Regular Composite SUCCESS */
1434 if (status_reg & BIT(comp_grp_id + 5)) {
1435 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1436 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001437 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001438 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001439
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001440 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001441 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001442 break;
1443
1444 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1445 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1446 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1447 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1448 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1449 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001450 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001451 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1452
1453 /* Check for DUAL composite error */
1454 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1455
1456 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1457 if ((status_reg & BIT(6)) &&
1458 (comp_err_reg & rsrc_data->composite_mask)) {
1459 /* Check for DUAL composite error */
1460 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1461 break;
1462 }
1463
1464 /* Check for Dual composite Overwrite */
1465 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1466 if ((status_reg & BIT(7)) &&
1467 (comp_err_reg & rsrc_data->composite_mask)) {
1468 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1469 break;
1470 }
1471
Harsh Shah23557ae2017-05-13 18:14:34 -07001472 /* DUAL Composite SUCCESS */
1473 if (status_reg & BIT(comp_grp_id)) {
1474 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1475 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001476 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001477 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001478
1479 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001480 default:
1481 rc = CAM_VFE_IRQ_STATUS_ERR;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001482 CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001483 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001484 break;
1485 }
1486
1487 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001488 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001489 &evt_payload);
1490
1491 return rc;
1492}
1493
1494static int cam_vfe_bus_init_comp_grp(uint32_t index,
1495 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1496 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1497 struct cam_isp_resource_node *comp_grp)
1498{
Harsh Shah545df9a2017-06-16 16:43:17 -07001499 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001500
1501 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1502 GFP_KERNEL);
1503 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001504 CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001505 return -ENOMEM;
1506 }
1507 comp_grp->res_priv = rsrc_data;
1508
1509 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1510 INIT_LIST_HEAD(&comp_grp->list);
1511
1512 rsrc_data->comp_grp_type = index;
1513 rsrc_data->common_data = &ver2_bus_priv->common_data;
1514 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1515 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1516
Harsh Shaha1af8822017-05-11 22:06:36 -07001517 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1518 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1519 list_add_tail(&comp_grp->list,
1520 &ver2_bus_priv->free_dual_comp_grp);
1521 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1522 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1523 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1524
1525 comp_grp->start = cam_vfe_bus_start_comp_grp;
1526 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1527 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1528 comp_grp->bottom_half_handler =
1529 cam_vfe_bus_handle_comp_done_bottom_half;
1530 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1531
1532 return 0;
1533}
1534
Harsh Shah545df9a2017-06-16 16:43:17 -07001535static int cam_vfe_bus_deinit_comp_grp(
1536 struct cam_isp_resource_node *comp_grp)
1537{
1538 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1539 comp_grp->res_priv;
1540
1541 comp_grp->start = NULL;
1542 comp_grp->stop = NULL;
1543 comp_grp->top_half_handler = NULL;
1544 comp_grp->bottom_half_handler = NULL;
1545 comp_grp->hw_intf = NULL;
1546
1547 list_del_init(&comp_grp->list);
1548 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1549
1550 comp_grp->res_priv = NULL;
1551
1552 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001553 CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001554 return -ENODEV;
1555 }
1556 kfree(rsrc_data);
1557
1558 return 0;
1559}
1560
Harsh Shah19f55812017-06-26 18:58:49 -07001561static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1562 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001563{
1564 int rc = -ENODEV;
1565 int i;
1566 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1567 uint32_t format;
1568 uint32_t num_wm;
1569 uint32_t subscribe_irq;
1570 uint32_t client_done_mask;
1571 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1572 struct cam_vfe_acquire_args *acq_args = acquire_args;
1573 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1574 struct cam_isp_resource_node *rsrc_node = NULL;
1575 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1576
1577 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001578 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001579 return -EINVAL;
1580 }
1581
1582 out_acquire_args = &acq_args->vfe_out;
1583 format = out_acquire_args->out_port_info->format;
1584
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001585 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001586 out_acquire_args->out_port_info->res_type);
1587
1588 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1589 out_acquire_args->out_port_info->res_type);
1590 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1591 return -ENODEV;
1592
1593 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1594 if (num_wm < 1)
1595 return -EINVAL;
1596
1597 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1598 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001599 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001600 vfe_out_res_id, rsrc_node->res_state);
1601 return -EBUSY;
1602 }
1603
1604 rsrc_data = rsrc_node->res_priv;
1605 rsrc_data->num_wm = num_wm;
1606 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1607 rsrc_node->tasklet_info = acq_args->tasklet;
1608 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1609 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1610
1611 /* Reserve Composite Group */
1612 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1613 CAM_ISP_RES_COMP_GROUP_NONE &&
1614 out_acquire_args->out_port_info->comp_grp_id <
1615 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1616 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1617 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001618 acq_args->tasklet,
1619 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001620 out_acquire_args->unique_id,
1621 out_acquire_args->is_dual,
1622 out_acquire_args->is_master,
1623 out_acquire_args->dual_slave_core,
1624 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001625 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001626 CAM_ERR(CAM_ISP,
1627 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001628 rsrc_data->common_data->core_index,
1629 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001630 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001631 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001632
1633 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001634 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001635 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001636 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001637
1638 /* Reserve WM */
1639 for (i = 0; i < num_wm; i++) {
1640 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1641 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001642 acq_args->tasklet,
1643 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001644 vfe_out_res_id,
1645 i,
1646 out_acquire_args->split_id,
1647 subscribe_irq,
1648 &rsrc_data->wm_res[i],
1649 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001650 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001651 CAM_ERR(CAM_ISP,
1652 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001653 rsrc_data->common_data->core_index,
1654 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001655 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001656 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001657
1658 if (rsrc_data->comp_grp)
1659 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1660 client_done_mask);
1661 }
1662
1663 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1664 out_acquire_args->rsrc_node = rsrc_node;
1665
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001666 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001667 return rc;
1668
1669release_wm:
1670 for (i--; i >= 0; i--)
1671 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1672
1673 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1674 rsrc_data->comp_grp);
1675
1676 return rc;
1677}
1678
Harsh Shah19f55812017-06-26 18:58:49 -07001679static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1680 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001681{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001682 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001683 struct cam_isp_resource_node *vfe_out = NULL;
1684 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1685
1686 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001687 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001688 bus_priv, release_args);
1689 return -EINVAL;
1690 }
1691
1692 vfe_out = release_args;
1693 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001694
Harsh Shaha1af8822017-05-11 22:06:36 -07001695 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001696 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001697 vfe_out->res_state);
1698 }
1699
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001700 for (i = 0; i < rsrc_data->num_wm; i++)
1701 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1702 rsrc_data->num_wm = 0;
1703
1704 if (rsrc_data->comp_grp)
1705 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1706 rsrc_data->comp_grp = NULL;
1707
1708 vfe_out->tasklet_info = NULL;
1709 vfe_out->cdm_ops = NULL;
1710 rsrc_data->cdm_util_ops = NULL;
1711
Harsh Shaha1af8822017-05-11 22:06:36 -07001712 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1713 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1714
1715 return 0;
1716}
1717
Harsh Shah19f55812017-06-26 18:58:49 -07001718static int cam_vfe_bus_start_vfe_out(
1719 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001720{
1721 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001722 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1723 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1724
1725 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001726 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001727 return -EINVAL;
1728 }
1729
1730 rsrc_data = vfe_out->res_priv;
1731 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001732
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001733 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001734
1735 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001736 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001737 vfe_out->res_state);
1738 return -EACCES;
1739 }
1740
1741 for (i = 0; i < rsrc_data->num_wm; i++)
1742 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1743
1744 if (rsrc_data->comp_grp)
1745 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1746
Harsh Shaha1af8822017-05-11 22:06:36 -07001747 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1748 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1749 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1750 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1751 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1752 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001753 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1754 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1755 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1756 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1757 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1758 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1759 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1760 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1761 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1762
Harsh Shah23557ae2017-05-13 18:14:34 -07001763 /* no clock gating at bus input */
1764 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1765
1766 /* BUS_WR_TEST_BUS_CTRL */
1767 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
1768
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05301769 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07001770 return rc;
1771}
1772
Harsh Shah19f55812017-06-26 18:58:49 -07001773static int cam_vfe_bus_stop_vfe_out(
1774 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001775{
1776 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001777 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1778
1779 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001780 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001781 return -EINVAL;
1782 }
1783
1784 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001785
1786 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
1787 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
1788 return rc;
1789 }
1790
1791 if (rsrc_data->comp_grp)
1792 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
1793
1794 for (i = 0; i < rsrc_data->num_wm; i++)
1795 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
1796
Harsh Shaha1af8822017-05-11 22:06:36 -07001797
1798 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1799 return rc;
1800}
1801
1802static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
1803 struct cam_irq_th_payload *th_payload)
1804{
1805 return -EPERM;
1806}
1807
1808static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
1809 void *handler_priv,
1810 void *evt_payload_priv)
1811{
1812 int rc = -EINVAL;
1813 struct cam_isp_resource_node *vfe_out = handler_priv;
1814 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1815
1816 /*
1817 * If this resource has Composite Group then we only handle
1818 * Composite done. We acquire Composite if number of WM > 1.
1819 * So Else case is only one individual buf_done = WM[0].
1820 */
1821 if (rsrc_data->comp_grp) {
1822 rc = rsrc_data->comp_grp->bottom_half_handler(
1823 rsrc_data->comp_grp, evt_payload_priv);
1824 } else {
1825 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07001826 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07001827 }
1828
1829 return rc;
1830}
1831
1832static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
1833 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1834 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1835 struct cam_isp_resource_node *vfe_out)
1836{
1837 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1838 int rc = 0;
1839
1840 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
1841 GFP_KERNEL);
1842 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001843 CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001844 rc = -ENOMEM;
1845 return rc;
1846 }
1847 vfe_out->res_priv = rsrc_data;
1848
1849 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
1850 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1851 INIT_LIST_HEAD(&vfe_out->list);
1852
1853 rsrc_data->out_type = index;
1854 rsrc_data->common_data = &ver2_bus_priv->common_data;
1855 rsrc_data->max_width =
1856 ver2_hw_info->vfe_out_hw_info[index].max_width;
1857 rsrc_data->max_height =
1858 ver2_hw_info->vfe_out_hw_info[index].max_height;
1859
1860 vfe_out->start = cam_vfe_bus_start_vfe_out;
1861 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
1862 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
1863 vfe_out->bottom_half_handler =
1864 cam_vfe_bus_handle_vfe_out_done_bottom_half;
1865 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
1866
1867 return 0;
1868}
1869
Harsh Shah545df9a2017-06-16 16:43:17 -07001870static int cam_vfe_bus_deinit_vfe_out_resource(
1871 struct cam_isp_resource_node *vfe_out)
1872{
1873 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1874
1875 vfe_out->start = NULL;
1876 vfe_out->stop = NULL;
1877 vfe_out->top_half_handler = NULL;
1878 vfe_out->bottom_half_handler = NULL;
1879 vfe_out->hw_intf = NULL;
1880
1881 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1882 INIT_LIST_HEAD(&vfe_out->list);
1883 vfe_out->res_priv = NULL;
1884
1885 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001886 CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001887 return -ENOMEM;
1888 }
1889 kfree(rsrc_data);
1890
1891 return 0;
1892}
1893
Harsh Shaha1af8822017-05-11 22:06:36 -07001894static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
1895 struct cam_irq_th_payload *th_payload)
1896{
Harsh Shaha1af8822017-05-11 22:06:36 -07001897 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001898
Harsh Shah19f55812017-06-26 18:58:49 -07001899 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001900 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07001901 return cam_irq_controller_handle_irq(evt_id,
1902 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07001903}
1904
1905static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
1906 uint32_t arg_size)
1907{
1908 struct cam_vfe_bus_ver2_priv *bus_priv;
1909 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001910 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07001911 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
1912 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001913 uint32_t *reg_val_pair;
1914 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07001915 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001916
1917 /*
1918 * Need the entire buf io config so we can get the stride info
1919 * for the wm.
1920 */
1921
1922 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
1923 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
1924
1925 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
1926 update_buf->cdm.res->res_priv;
1927
1928 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001929 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07001930 return -EINVAL;
1931 }
1932
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001933 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001934 CAM_ERR(CAM_ISP,
1935 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001936 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07001937 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001938 }
1939
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001940 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
1941 io_cfg = update_buf->io_cfg;
1942
1943 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07001944 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001945 CAM_ERR(CAM_ISP,
1946 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07001947 j, MAX_REG_VAL_PAIR_SIZE);
1948 return -ENOMEM;
1949 }
1950
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001951 wm_data = vfe_out_data->wm_res[i]->res_priv;
1952
1953 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301954 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
1955 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001956 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1957 wm_data->hw_regs->stride,
1958 io_cfg->planes[i].plane_stride);
1959 wm_data->stride = io_cfg->planes[i].plane_stride;
1960 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001961 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001962
1963 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07001964 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001965 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1966 wm_data->hw_regs->framedrop_pattern,
1967 io_cfg->framedrop_pattern);
1968 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
1969 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001970 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
1971 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001972
1973 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07001974 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001975 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1976 wm_data->hw_regs->framedrop_period,
1977 io_cfg->framedrop_period);
1978 wm_data->framedrop_period = io_cfg->framedrop_period;
1979 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001980 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
1981 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001982
1983 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07001984 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001985 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1986 wm_data->hw_regs->irq_subsample_period,
1987 io_cfg->subsample_period);
1988 wm_data->irq_subsample_period =
1989 io_cfg->subsample_period;
1990 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001991 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001992 wm_data->irq_subsample_period);
1993
1994 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07001995 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001996 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1997 wm_data->hw_regs->irq_subsample_pattern,
1998 io_cfg->subsample_pattern);
1999 wm_data->irq_subsample_pattern =
2000 io_cfg->subsample_pattern;
2001 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002002 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002003 wm_data->irq_subsample_pattern);
2004
2005 if (wm_data->en_ubwc) {
2006 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002007 CAM_ERR(CAM_ISP,
2008 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002009 return -EINVAL;
2010 }
2011 if (wm_data->packer_cfg !=
2012 io_cfg->planes[i].packer_config ||
2013 !wm_data->init_cfg_done) {
2014 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2015 wm_data->hw_regs->packer_cfg,
2016 io_cfg->planes[i].packer_config);
2017 wm_data->packer_cfg =
2018 io_cfg->planes[i].packer_config;
2019 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002020 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2021 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002022
2023 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
2024 || !wm_data->init_cfg_done) {
2025 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2026 wm_data->hw_regs->ubwc_regs->tile_cfg,
2027 io_cfg->planes[i].tile_config);
2028 wm_data->tile_cfg =
2029 io_cfg->planes[i].tile_config;
2030 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002031 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002032
2033 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2034 !wm_data->init_cfg_done) {
2035 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2036 wm_data->hw_regs->ubwc_regs->h_init,
2037 io_cfg->planes[i].h_init);
2038 wm_data->h_init = io_cfg->planes[i].h_init;
2039 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002040 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002041
2042 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2043 !wm_data->init_cfg_done) {
2044 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2045 wm_data->hw_regs->ubwc_regs->v_init,
2046 io_cfg->planes[i].v_init);
2047 wm_data->v_init = io_cfg->planes[i].v_init;
2048 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002049 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002050
2051 if (wm_data->ubwc_meta_stride !=
2052 io_cfg->planes[i].meta_stride ||
2053 !wm_data->init_cfg_done) {
2054 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2055 wm_data->hw_regs->ubwc_regs->
2056 meta_stride,
2057 io_cfg->planes[i].meta_stride);
2058 wm_data->ubwc_meta_stride =
2059 io_cfg->planes[i].meta_stride;
2060 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002061 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2062 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002063
2064 if (wm_data->ubwc_mode_cfg !=
2065 io_cfg->planes[i].mode_config ||
2066 !wm_data->init_cfg_done) {
2067 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2068 wm_data->hw_regs->ubwc_regs->mode_cfg,
2069 io_cfg->planes[i].mode_config);
2070 wm_data->ubwc_mode_cfg =
2071 io_cfg->planes[i].mode_config;
2072 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002073 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2074 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002075
2076 if (wm_data->ubwc_meta_offset !=
2077 io_cfg->planes[i].meta_offset ||
2078 !wm_data->init_cfg_done) {
2079 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2080 wm_data->hw_regs->ubwc_regs->
2081 meta_offset,
2082 io_cfg->planes[i].meta_offset);
2083 wm_data->ubwc_meta_offset =
2084 io_cfg->planes[i].meta_offset;
2085 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002086 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002087 wm_data->ubwc_meta_offset);
2088
2089 /* UBWC meta address */
2090 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2091 wm_data->hw_regs->ubwc_regs->meta_addr,
2092 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002093 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002094 update_buf->image_buf[i]);
2095 }
2096
2097 /* WM Image address */
2098 if (wm_data->en_ubwc)
2099 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2100 wm_data->hw_regs->image_addr,
2101 (update_buf->image_buf[i] +
2102 io_cfg->planes[i].meta_size));
2103 else
2104 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2105 wm_data->hw_regs->image_addr,
2106 update_buf->image_buf[i]);
2107
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002108 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002109
Junzhe Zou193d78c2017-05-16 15:10:54 -07002110 frame_inc = io_cfg->planes[i].plane_stride *
2111 io_cfg->planes[i].slice_height;
2112 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2113 wm_data->hw_regs->frame_inc, frame_inc);
2114
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002115 /* enable the WM */
2116 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2117 wm_data->hw_regs->cfg,
2118 wm_data->en_cfg);
2119
2120 /* set initial configuration done */
2121 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002122 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002123 }
2124
2125 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002126
2127 /* cdm util returns dwords, need to convert to bytes */
2128 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002129 CAM_ERR(CAM_ISP,
2130 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002131 update_buf->cdm.size, size);
2132 return -ENOMEM;
2133 }
2134
Harsh Shaha1af8822017-05-11 22:06:36 -07002135 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002136 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2137
Harsh Shaha1af8822017-05-11 22:06:36 -07002138 /* cdm util returns dwords, need to convert to bytes */
2139 update_buf->cdm.used_bytes = size * 4;
2140
2141 return 0;
2142}
2143
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002144static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2145 uint32_t arg_size)
2146{
2147 struct cam_vfe_bus_ver2_priv *bus_priv;
2148 struct cam_isp_hw_get_hfr_update *update_hfr;
2149 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2150 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2151 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2152 uint32_t *reg_val_pair;
2153 uint32_t i, j, size = 0;
2154
2155 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2156 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2157
2158 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2159 update_hfr->cdm.res->res_priv;
2160
2161 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2162 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2163 return -EINVAL;
2164 }
2165
2166 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2167 hfr_cfg = update_hfr->io_hfr_cfg;
2168
2169 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2170 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2171 CAM_ERR(CAM_ISP,
2172 "reg_val_pair %d exceeds the array limit %lu",
2173 j, MAX_REG_VAL_PAIR_SIZE);
2174 return -ENOMEM;
2175 }
2176
2177 wm_data = vfe_out_data->wm_res[i]->res_priv;
2178
2179 if ((wm_data->framedrop_pattern !=
2180 hfr_cfg->framedrop_pattern) ||
2181 !wm_data->hfr_cfg_done) {
2182 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2183 wm_data->hw_regs->framedrop_pattern,
2184 hfr_cfg->framedrop_pattern);
2185 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2186 }
2187 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2188 wm_data->framedrop_pattern);
2189
2190 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2191 !wm_data->hfr_cfg_done) {
2192 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2193 wm_data->hw_regs->framedrop_period,
2194 hfr_cfg->framedrop_period);
2195 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2196 }
2197 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2198 wm_data->framedrop_period);
2199
2200 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2201 || !wm_data->hfr_cfg_done) {
2202 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2203 wm_data->hw_regs->irq_subsample_period,
2204 hfr_cfg->subsample_period);
2205 wm_data->irq_subsample_period =
2206 hfr_cfg->subsample_period;
2207 }
2208 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2209 wm_data->irq_subsample_period);
2210
2211 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2212 || !wm_data->hfr_cfg_done) {
2213 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2214 wm_data->hw_regs->irq_subsample_pattern,
2215 hfr_cfg->subsample_pattern);
2216 wm_data->irq_subsample_pattern =
2217 hfr_cfg->subsample_pattern;
2218 }
2219 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2220 wm_data->irq_subsample_pattern);
2221
2222 /* set initial configuration done */
2223 if (!wm_data->hfr_cfg_done)
2224 wm_data->hfr_cfg_done = true;
2225 }
2226
2227 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2228
2229 /* cdm util returns dwords, need to convert to bytes */
2230 if ((size * 4) > update_hfr->cdm.size) {
2231 CAM_ERR(CAM_ISP,
2232 "Failed! Buf size:%d insufficient, expected size:%d",
2233 update_hfr->cdm.size, size);
2234 return -ENOMEM;
2235 }
2236
2237 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2238 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2239
2240 /* cdm util returns dwords, need to convert to bytes */
2241 update_hfr->cdm.used_bytes = size * 4;
2242
2243 return 0;
2244}
2245
Harsh Shah19f55812017-06-26 18:58:49 -07002246static int cam_vfe_bus_start_hw(void *hw_priv,
2247 void *start_hw_args, uint32_t arg_size)
2248{
2249 return cam_vfe_bus_start_vfe_out(hw_priv);
2250}
2251
2252static int cam_vfe_bus_stop_hw(void *hw_priv,
2253 void *stop_hw_args, uint32_t arg_size)
2254{
2255 return cam_vfe_bus_stop_vfe_out(hw_priv);
2256}
2257
2258static int cam_vfe_bus_init_hw(void *hw_priv,
2259 void *init_hw_args, uint32_t arg_size)
2260{
2261 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2262 uint32_t top_irq_reg_mask[2] = {0};
2263
2264 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002265 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002266 return -EINVAL;
2267 }
2268
2269 top_irq_reg_mask[0] = (1 << 9);
2270
2271 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2272 bus_priv->common_data.vfe_irq_controller,
2273 CAM_IRQ_PRIORITY_2,
2274 top_irq_reg_mask,
2275 bus_priv,
2276 cam_vfe_bus_ver2_handle_irq,
2277 NULL,
2278 NULL,
2279 NULL);
2280
2281 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002282 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002283 return -EFAULT;
2284 }
2285
2286 return 0;
2287}
2288
2289static int cam_vfe_bus_deinit_hw(void *hw_priv,
2290 void *deinit_hw_args, uint32_t arg_size)
2291{
2292 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2293 int rc;
2294
2295 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002296 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002297 return -EINVAL;
2298 }
2299
2300 rc = cam_irq_controller_unsubscribe_irq(
2301 bus_priv->common_data.vfe_irq_controller,
2302 bus_priv->irq_handle);
2303 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002304 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002305
2306 return rc;
2307}
2308
Harsh Shaha1af8822017-05-11 22:06:36 -07002309static int cam_vfe_bus_process_cmd(void *priv,
2310 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2311{
2312 int rc = -EINVAL;
2313
2314 if (!priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002315 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
Harsh Shaha1af8822017-05-11 22:06:36 -07002316 return -EINVAL;
2317 }
2318
2319 switch (cmd_type) {
2320 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2321 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2322 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002323 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2324 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2325 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002326 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002327 CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
Harsh Shaha1af8822017-05-11 22:06:36 -07002328 cmd_type);
2329 break;
2330 }
2331
2332 return rc;
2333}
2334
2335int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002336 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002337 struct cam_hw_intf *hw_intf,
2338 void *bus_hw_info,
2339 void *vfe_irq_controller,
2340 struct cam_vfe_bus **vfe_bus)
2341{
2342 int i, rc = 0;
2343 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2344 struct cam_vfe_bus *vfe_bus_local;
2345 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2346
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002347 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002348
Harsh Shah19f55812017-06-26 18:58:49 -07002349 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002350 CAM_ERR(CAM_ISP,
2351 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2352 soc_info, hw_intf, bus_hw_info);
2353 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002354 rc = -EINVAL;
2355 goto end;
2356 }
2357
Harsh Shaha1af8822017-05-11 22:06:36 -07002358 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2359 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002360 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002361 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002362 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002363 }
2364
2365 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2366 GFP_KERNEL);
2367 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002368 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002369 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002370 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002371 }
2372 vfe_bus_local->bus_priv = bus_priv;
2373
Harsh Shah19f55812017-06-26 18:58:49 -07002374 bus_priv->common_data.core_index = soc_info->index;
2375 bus_priv->common_data.mem_base =
2376 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002377 bus_priv->common_data.hw_intf = hw_intf;
2378 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2379 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
2380
Harsh Shah19f55812017-06-26 18:58:49 -07002381 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2382 &ver2_hw_info->common_reg.irq_reg_info,
2383 &bus_priv->common_data.bus_irq_controller);
2384 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002385 CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002386 goto free_bus_priv;
2387 }
2388
Harsh Shaha1af8822017-05-11 22:06:36 -07002389 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2390 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2391 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2392
2393 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2394 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2395 &bus_priv->bus_client[i]);
2396 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002397 CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002398 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002399 }
2400 }
2401
2402 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2403 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2404 &bus_priv->comp_grp[i]);
2405 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002406 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002407 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002408 }
2409 }
2410
2411 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2412 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2413 &bus_priv->vfe_out[i]);
2414 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002415 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002416 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002417 }
2418 }
2419
Harsh Shah19f55812017-06-26 18:58:49 -07002420 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2421 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2422 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2423 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2424 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002425 }
2426
Harsh Shah19f55812017-06-26 18:58:49 -07002427 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2428 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2429 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2430 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2431 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2432 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2433 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002434 vfe_bus_local->bottom_half_handler = NULL;
Harsh Shah19f55812017-06-26 18:58:49 -07002435 vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002436
2437 *vfe_bus = vfe_bus_local;
2438
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002439 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002440 return rc;
2441
Harsh Shah545df9a2017-06-16 16:43:17 -07002442deinit_vfe_out:
2443 if (i < 0)
2444 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2445 for (--i; i >= 0; i--)
2446 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2447
2448deinit_comp_grp:
2449 if (i < 0)
2450 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2451 for (--i; i >= 0; i--)
2452 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2453
2454deinit_wm:
2455 if (i < 0)
2456 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2457 for (--i; i >= 0; i--)
2458 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2459
Harsh Shah19f55812017-06-26 18:58:49 -07002460free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002461 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002462
2463free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002464 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002465
2466end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002467 return rc;
2468}
Harsh Shah545df9a2017-06-16 16:43:17 -07002469
2470int cam_vfe_bus_ver2_deinit(
2471 struct cam_vfe_bus **vfe_bus)
2472{
2473 int i, rc = 0;
2474 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2475 struct cam_vfe_bus *vfe_bus_local;
2476
2477 if (!vfe_bus || !*vfe_bus) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002478 CAM_ERR(CAM_ISP, "Error! Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002479 return -EINVAL;
2480 }
2481 vfe_bus_local = *vfe_bus;
2482
2483 bus_priv = vfe_bus_local->bus_priv;
2484 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002485 CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002486 rc = -ENODEV;
2487 goto free_bus_local;
2488 }
2489
Harsh Shah19f55812017-06-26 18:58:49 -07002490 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2491 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2492 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002493
2494 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2495 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2496 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002497 CAM_ERR(CAM_ISP,
2498 "Error! Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002499 }
2500
2501 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2502 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2503 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002504 CAM_ERR(CAM_ISP,
2505 "Error! Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002506 }
2507
2508 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2509 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2510 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002511 CAM_ERR(CAM_ISP,
2512 "Error! Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002513 }
2514
2515 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2516 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2517 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2518
Harsh Shah19f55812017-06-26 18:58:49 -07002519 rc = cam_irq_controller_deinit(
2520 &bus_priv->common_data.bus_irq_controller);
2521 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002522 CAM_ERR(CAM_ISP,
2523 "Error! Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002524
Harsh Shah545df9a2017-06-16 16:43:17 -07002525 kfree(vfe_bus_local->bus_priv);
2526
2527free_bus_local:
2528 kfree(vfe_bus_local);
2529
2530 *vfe_bus = NULL;
2531
2532 return rc;
2533}
2534