blob: f37ec386ef1f721d47211f465316969e455a7a46 [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
Junzhe Zou193d78c2017-05-16 15:10:54 -070039#define MAX_BUF_UPDATE_REG_NUM \
40 (sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070041#define MAX_REG_VAL_PAIR_SIZE \
Harsh Shah19f55812017-06-26 18:58:49 -070042 (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070043
44#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
Harsh Shah19f55812017-06-26 18:58:49 -070045 do { \
46 buf_array[index++] = offset; \
47 buf_array[index++] = val; \
48 } while (0)
Harsh Shaha1af8822017-05-11 22:06:36 -070049
50enum cam_vfe_bus_packer_format {
51 PACKER_FMT_PLAIN_128 = 0x0,
52 PACKER_FMT_PLAIN_8 = 0x1,
53 PACKER_FMT_PLAIN_16_10BPP = 0x2,
54 PACKER_FMT_PLAIN_16_12BPP = 0x3,
55 PACKER_FMT_PLAIN_16_14BPP = 0x4,
56 PACKER_FMT_PLAIN_16_16BPP = 0x5,
57 PACKER_FMT_ARGB_10 = 0x6,
58 PACKER_FMT_ARGB_12 = 0x7,
59 PACKER_FMT_ARGB_14 = 0x8,
60 PACKER_FMT_PLAIN_32_20BPP = 0x9,
61 PACKER_FMT_PLAIN_64 = 0xA,
62 PACKER_FMT_TP_10 = 0xB,
63 PACKER_FMT_PLAIN_32_32BPP = 0xC,
64 PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
65 PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
66 PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
67 PACKER_FMT_MAX = 0xF,
68};
69
70struct cam_vfe_bus_ver2_common_data {
Harsh Shah19f55812017-06-26 18:58:49 -070071 uint32_t core_index;
Harsh Shaha1af8822017-05-11 22:06:36 -070072 void __iomem *mem_base;
73 struct cam_hw_intf *hw_intf;
74 void *bus_irq_controller;
75 void *vfe_irq_controller;
76 struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070077 uint32_t io_buf_update[
Harsh Shah19f55812017-06-26 18:58:49 -070078 MAX_REG_VAL_PAIR_SIZE];
79
80 struct cam_vfe_bus_irq_evt_payload evt_payload[
81 CAM_VFE_BUS_VER2_PAYLOAD_MAX];
82 struct list_head free_payload_list;
Harsh Shaha1af8822017-05-11 22:06:36 -070083};
84
85struct cam_vfe_bus_ver2_wm_resource_data {
86 uint32_t index;
87 struct cam_vfe_bus_ver2_common_data *common_data;
88 struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
Harsh Shah19f55812017-06-26 18:58:49 -070089 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -070090
91 uint32_t irq_enabled;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070092 uint32_t init_cfg_done;
Harsh Shah19f55812017-06-26 18:58:49 -070093
Harsh Shaha1af8822017-05-11 22:06:36 -070094 uint32_t offset;
95 uint32_t width;
96 uint32_t height;
97 uint32_t stride;
98 uint32_t format;
99 enum cam_vfe_bus_packer_format pack_fmt;
100
101 uint32_t burst_len;
102 uint32_t frame_based;
103
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700104 uint32_t en_ubwc;
105 uint32_t packer_cfg;
106 uint32_t tile_cfg;
107 uint32_t h_init;
108 uint32_t v_init;
109 uint32_t ubwc_meta_stride;
110 uint32_t ubwc_mode_cfg;
111 uint32_t ubwc_meta_offset;
112
Harsh Shaha1af8822017-05-11 22:06:36 -0700113 uint32_t irq_subsample_period;
114 uint32_t irq_subsample_pattern;
115 uint32_t framedrop_period;
116 uint32_t framedrop_pattern;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700117
118 uint32_t en_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -0700119};
120
121struct cam_vfe_bus_ver2_comp_grp_data {
122 enum cam_vfe_bus_ver2_comp_grp_type comp_grp_type;
123 struct cam_vfe_bus_ver2_common_data *common_data;
124 struct cam_vfe_bus_ver2_reg_offset_comp_grp *hw_regs;
125
126 uint32_t irq_enabled;
127 uint32_t comp_grp_local_idx;
128 uint32_t unique_id;
129
130 uint32_t is_master;
131 uint32_t dual_slave_core;
132 uint32_t intra_client_mask;
133 uint32_t composite_mask;
Harsh Shah19f55812017-06-26 18:58:49 -0700134
135 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700136};
137
138struct cam_vfe_bus_ver2_vfe_out_data {
139 uint32_t out_type;
140 struct cam_vfe_bus_ver2_common_data *common_data;
141
142 uint32_t num_wm;
143 struct cam_isp_resource_node *wm_res[PLANE_MAX];
144
145 struct cam_isp_resource_node *comp_grp;
146 enum cam_isp_hw_sync_mode dual_comp_sync_mode;
147 uint32_t dual_hw_alternate_vfe_id;
148 struct list_head vfe_out_list;
149
150 uint32_t format;
151 uint32_t max_width;
152 uint32_t max_height;
153 struct cam_cdm_utils_ops *cdm_util_ops;
154};
155
Harsh Shaha1af8822017-05-11 22:06:36 -0700156struct cam_vfe_bus_ver2_priv {
157 struct cam_vfe_bus_ver2_common_data common_data;
158
159 struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
160 struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
161 struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
162
163 struct list_head free_comp_grp;
164 struct list_head free_dual_comp_grp;
165 struct list_head used_comp_grp;
166
Harsh Shah19f55812017-06-26 18:58:49 -0700167 uint32_t irq_handle;
Harsh Shaha1af8822017-05-11 22:06:36 -0700168};
169
Harsh Shah19f55812017-06-26 18:58:49 -0700170static int cam_vfe_bus_get_evt_payload(
171 struct cam_vfe_bus_ver2_common_data *common_data,
172 struct cam_vfe_bus_irq_evt_payload **evt_payload)
173{
174 if (list_empty(&common_data->free_payload_list)) {
175 *evt_payload = NULL;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700176 CAM_ERR(CAM_ISP, "No free payload");
Harsh Shah19f55812017-06-26 18:58:49 -0700177 return -ENODEV;
178 }
179
180 *evt_payload = list_first_entry(&common_data->free_payload_list,
181 struct cam_vfe_bus_irq_evt_payload, list);
182 list_del_init(&(*evt_payload)->list);
183 return 0;
184}
185
Harsh Shaha1af8822017-05-11 22:06:36 -0700186static int cam_vfe_bus_put_evt_payload(void *core_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700187 struct cam_vfe_bus_irq_evt_payload **evt_payload)
188{
189 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
190 uint32_t *ife_irq_regs = NULL;
191 uint32_t status_reg0, status_reg1, status_reg2;
192
193 if (!core_info) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700194 CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
Harsh Shah19f55812017-06-26 18:58:49 -0700195 return -EINVAL;
196 }
197 if (*evt_payload == NULL) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700198 CAM_ERR(CAM_ISP, "No payload to put");
Harsh Shah19f55812017-06-26 18:58:49 -0700199 return -EINVAL;
200 }
201
202 ife_irq_regs = (*evt_payload)->irq_reg_val;
203 status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
204 status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
205 status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
206
207 if (status_reg0 || status_reg1 || status_reg2) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700208 CAM_DBG(CAM_ISP, "status0 0x%x status1 0x%x status2 0x%x",
Harsh Shah19f55812017-06-26 18:58:49 -0700209 status_reg0, status_reg1, status_reg2);
210 return 0;
211 }
212
213 common_data = core_info;
214 list_add_tail(&(*evt_payload)->list,
215 &common_data->free_payload_list);
216 *evt_payload = NULL;
217
218 return 0;
219}
Harsh Shaha1af8822017-05-11 22:06:36 -0700220
221static int cam_vfe_bus_ver2_get_intra_client_mask(
222 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
223 enum cam_vfe_bus_ver2_vfe_core_id current_core,
224 uint32_t *intra_client_mask)
225{
226 int rc = 0;
227
228 *intra_client_mask = 0;
229
230 if (dual_slave_core == current_core) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700231 CAM_ERR(CAM_ISP,
232 "Invalid params. Same core as Master and Slave");
Harsh Shaha1af8822017-05-11 22:06:36 -0700233 return -EINVAL;
234 }
235
236 switch (current_core) {
237 case CAM_VFE_BUS_VER2_VFE_CORE_0:
238 switch (dual_slave_core) {
239 case CAM_VFE_BUS_VER2_VFE_CORE_1:
240 *intra_client_mask = 0x1;
241 break;
242 case CAM_VFE_BUS_VER2_VFE_CORE_2:
243 *intra_client_mask = 0x2;
244 break;
245 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700246 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700247 dual_slave_core);
248 rc = -EINVAL;
249 break;
250 }
251 break;
252 case CAM_VFE_BUS_VER2_VFE_CORE_1:
253 switch (dual_slave_core) {
254 case CAM_VFE_BUS_VER2_VFE_CORE_0:
255 *intra_client_mask = 0x1;
256 break;
257 case CAM_VFE_BUS_VER2_VFE_CORE_2:
258 *intra_client_mask = 0x2;
259 break;
260 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700261 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700262 dual_slave_core);
263 rc = -EINVAL;
264 break;
265 }
266 break;
267 case CAM_VFE_BUS_VER2_VFE_CORE_2:
268 switch (dual_slave_core) {
269 case CAM_VFE_BUS_VER2_VFE_CORE_0:
270 *intra_client_mask = 0x1;
271 break;
272 case CAM_VFE_BUS_VER2_VFE_CORE_1:
273 *intra_client_mask = 0x2;
274 break;
275 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700276 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700277 dual_slave_core);
278 rc = -EINVAL;
279 break;
280 }
281 break;
282 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700283 CAM_ERR(CAM_ISP,
284 "Invalid value for master core %u", current_core);
Harsh Shaha1af8822017-05-11 22:06:36 -0700285 rc = -EINVAL;
286 break;
287 }
288
289 return rc;
290}
291
292static enum cam_vfe_bus_ver2_vfe_out_type
293 cam_vfe_bus_get_out_res_id(uint32_t res_type)
294{
295 switch (res_type) {
296 case CAM_ISP_IFE_OUT_RES_FULL:
297 return CAM_VFE_BUS_VER2_VFE_OUT_FULL;
298 case CAM_ISP_IFE_OUT_RES_DS4:
299 return CAM_VFE_BUS_VER2_VFE_OUT_DS4;
300 case CAM_ISP_IFE_OUT_RES_DS16:
301 return CAM_VFE_BUS_VER2_VFE_OUT_DS16;
302 case CAM_ISP_IFE_OUT_RES_FD:
303 return CAM_VFE_BUS_VER2_VFE_OUT_FD;
304 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
305 return CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP;
306 case CAM_ISP_IFE_OUT_RES_PDAF:
307 return CAM_VFE_BUS_VER2_VFE_OUT_PDAF;
308 case CAM_ISP_IFE_OUT_RES_RDI_0:
309 return CAM_VFE_BUS_VER2_VFE_OUT_RDI0;
310 case CAM_ISP_IFE_OUT_RES_RDI_1:
311 return CAM_VFE_BUS_VER2_VFE_OUT_RDI1;
312 case CAM_ISP_IFE_OUT_RES_RDI_2:
313 return CAM_VFE_BUS_VER2_VFE_OUT_RDI2;
314 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
315 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE;
316 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
317 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST;
318 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
319 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG;
320 case CAM_ISP_IFE_OUT_RES_STATS_BF:
321 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF;
322 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
323 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG;
324 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
325 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST;
326 case CAM_ISP_IFE_OUT_RES_STATS_RS:
327 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS;
328 case CAM_ISP_IFE_OUT_RES_STATS_CS:
329 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS;
330 case CAM_ISP_IFE_OUT_RES_STATS_IHIST:
331 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST;
332 default:
333 return CAM_VFE_BUS_VER2_VFE_OUT_MAX;
334 }
335}
336
337static int cam_vfe_bus_get_num_wm(
338 enum cam_vfe_bus_ver2_vfe_out_type res_type,
339 uint32_t format)
340{
341 switch (res_type) {
342 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
343 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
344 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
345 switch (format) {
346 case CAM_FORMAT_MIPI_RAW_8:
347 case CAM_FORMAT_MIPI_RAW_10:
348 case CAM_FORMAT_MIPI_RAW_12:
349 case CAM_FORMAT_MIPI_RAW_14:
350 case CAM_FORMAT_MIPI_RAW_16:
351 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530352 case CAM_FORMAT_DPCM_10_6_10:
353 case CAM_FORMAT_DPCM_10_8_10:
354 case CAM_FORMAT_DPCM_12_6_12:
355 case CAM_FORMAT_DPCM_12_8_12:
356 case CAM_FORMAT_DPCM_14_8_14:
357 case CAM_FORMAT_DPCM_14_10_14:
358 case CAM_FORMAT_PLAIN8:
359 case CAM_FORMAT_PLAIN16_8:
360 case CAM_FORMAT_PLAIN16_10:
361 case CAM_FORMAT_PLAIN16_12:
362 case CAM_FORMAT_PLAIN16_14:
363 case CAM_FORMAT_PLAIN16_16:
364 case CAM_FORMAT_PLAIN32_20:
Harsh Shaha1af8822017-05-11 22:06:36 -0700365 case CAM_FORMAT_PLAIN128:
366 return 1;
367 default:
368 break;
369 }
370 break;
371 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
372 switch (format) {
373 case CAM_FORMAT_NV21:
374 case CAM_FORMAT_NV12:
375 case CAM_FORMAT_MIPI_RAW_8:
376 case CAM_FORMAT_PLAIN8:
377 case CAM_FORMAT_TP10:
378 case CAM_FORMAT_UBWC_NV12:
379 case CAM_FORMAT_UBWC_NV12_4R:
380 case CAM_FORMAT_UBWC_TP10:
381 case CAM_FORMAT_UBWC_P010:
382 return 2;
383 default:
384 break;
385 }
386 break;
387 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
388 switch (format) {
389 case CAM_FORMAT_NV21:
390 case CAM_FORMAT_NV12:
391 case CAM_FORMAT_PLAIN8:
392 case CAM_FORMAT_TP10:
393 case CAM_FORMAT_PLAIN16_10:
394 return 2;
395 default:
396 break;
397 }
398 break;
399 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
400 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
401 switch (format) {
402 case CAM_FORMAT_PD8:
403 case CAM_FORMAT_PD10:
404 return 1;
405 default:
406 break;
407 }
408 break;
409 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
410 switch (format) {
411 case CAM_FORMAT_ARGB_14:
412 case CAM_FORMAT_PLAIN8:
413 case CAM_FORMAT_PLAIN16_10:
414 case CAM_FORMAT_PLAIN16_12:
415 case CAM_FORMAT_PLAIN16_14:
416 return 1;
417 default:
418 break;
419 }
420 break;
421 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
422 switch (format) {
423 case CAM_FORMAT_PLAIN8:
424 case CAM_FORMAT_PLAIN16_10:
425 case CAM_FORMAT_PLAIN16_12:
426 case CAM_FORMAT_PLAIN16_14:
427 return 1;
428 default:
429 break;
430 }
431 break;
432 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
433 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
434 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
435 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
436 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
437 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
438 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
439 switch (format) {
440 case CAM_FORMAT_PLAIN64:
441 return 1;
442 default:
443 break;
444 }
445 break;
446 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
447 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
448 switch (format) {
449 case CAM_FORMAT_PLAIN16_16:
450 return 1;
451 default:
452 break;
453 }
454 break;
455 default:
456 break;
457 }
458
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700459 CAM_ERR(CAM_ISP, "Unsupported format %u for resource_type %u",
460 format, res_type);
Harsh Shaha1af8822017-05-11 22:06:36 -0700461
462 return -EINVAL;
463}
464
465static int cam_vfe_bus_get_wm_idx(
466 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
467 enum cam_vfe_bus_plane_type plane)
468{
469 int wm_idx = -1;
470
471 switch (vfe_out_res_id) {
472 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
473 switch (plane) {
474 case PLANE_Y:
475 wm_idx = 3;
476 break;
477 case PLANE_C:
478 wm_idx = 4;
479 break;
480 default:
481 break;
482 }
483 break;
484 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
485 switch (plane) {
486 case PLANE_Y:
487 wm_idx = 5;
488 break;
489 default:
490 break;
491 }
492 break;
493 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
494 switch (plane) {
495 case PLANE_Y:
496 wm_idx = 6;
497 break;
498 default:
499 break;
500 }
501 break;
502 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
503 switch (plane) {
504 case PLANE_Y:
505 wm_idx = 7;
506 break;
507 case PLANE_C:
508 wm_idx = 8;
509 break;
510 default:
511 break;
512 }
513 break;
514 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
515 switch (plane) {
516 case PLANE_Y:
517 wm_idx = 9;
518 break;
519 default:
520 break;
521 }
522 break;
523 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
524 switch (plane) {
525 case PLANE_Y:
526 wm_idx = 10;
527 break;
528 default:
529 break;
530 }
531 break;
532 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
533 switch (plane) {
534 case PLANE_Y:
535 wm_idx = 0;
536 break;
537 default:
538 break;
539 }
540 break;
541 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
542 switch (plane) {
543 case PLANE_Y:
544 wm_idx = 1;
545 break;
546 default:
547 break;
548 }
549 break;
550 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
551 switch (plane) {
552 case PLANE_Y:
553 wm_idx = 2;
554 break;
555 default:
556 break;
557 }
558 break;
559 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
560 switch (plane) {
561 case PLANE_Y:
562 wm_idx = 11;
563 break;
564 default:
565 break;
566 }
567 break;
568 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
569 switch (plane) {
570 case PLANE_Y:
571 wm_idx = 12;
572 break;
573 default:
574 break;
575 }
576 break;
577 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
578 switch (plane) {
579 case PLANE_Y:
580 wm_idx = 13;
581 break;
582 default:
583 break;
584 }
585 break;
586 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
587 switch (plane) {
588 case PLANE_Y:
589 wm_idx = 14;
590 break;
591 default:
592 break;
593 }
594 break;
595 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
596 switch (plane) {
597 case PLANE_Y:
598 wm_idx = 15;
599 break;
600 default:
601 break;
602 }
603 break;
604 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
605 switch (plane) {
606 case PLANE_Y:
607 wm_idx = 16;
608 break;
609 default:
610 break;
611 }
612 break;
613 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
614 switch (plane) {
615 case PLANE_Y:
616 wm_idx = 17;
617 break;
618 default:
619 break;
620 }
621 break;
622 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
623 switch (plane) {
624 case PLANE_Y:
625 wm_idx = 18;
626 break;
627 default:
628 break;
629 }
630 break;
631 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
632 switch (plane) {
633 case PLANE_Y:
634 wm_idx = 19;
635 break;
636 default:
637 break;
638 }
639 break;
640 default:
641 break;
642 }
643
644 return wm_idx;
645}
646
647static enum cam_vfe_bus_packer_format
648 cam_vfe_bus_get_packer_fmt(uint32_t out_fmt)
649{
650 switch (out_fmt) {
651 case CAM_FORMAT_NV21:
652 case CAM_FORMAT_NV12:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530653 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530654 case CAM_FORMAT_PLAIN64:
655 return PACKER_FMT_PLAIN_64;
656 case CAM_FORMAT_MIPI_RAW_6:
657 case CAM_FORMAT_MIPI_RAW_8:
658 case CAM_FORMAT_MIPI_RAW_10:
659 case CAM_FORMAT_MIPI_RAW_12:
660 case CAM_FORMAT_MIPI_RAW_14:
661 case CAM_FORMAT_MIPI_RAW_16:
662 case CAM_FORMAT_MIPI_RAW_20:
663 case CAM_FORMAT_QTI_RAW_8:
664 case CAM_FORMAT_QTI_RAW_10:
665 case CAM_FORMAT_QTI_RAW_12:
666 case CAM_FORMAT_QTI_RAW_14:
667 case CAM_FORMAT_PLAIN128:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530668 case CAM_FORMAT_PLAIN8:
669 case CAM_FORMAT_PLAIN16_8:
670 case CAM_FORMAT_PLAIN16_10:
671 case CAM_FORMAT_PLAIN16_12:
672 case CAM_FORMAT_PLAIN16_14:
673 case CAM_FORMAT_PLAIN16_16:
674 case CAM_FORMAT_PLAIN32_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530675 case CAM_FORMAT_PD8:
676 case CAM_FORMAT_PD10:
677 return PACKER_FMT_PLAIN_128;
Harsh Shaha1af8822017-05-11 22:06:36 -0700678 default:
679 return PACKER_FMT_MAX;
680 }
681}
682
683static int cam_vfe_bus_acquire_wm(
684 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
685 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700686 void *tasklet,
687 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700688 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
689 enum cam_vfe_bus_plane_type plane,
690 enum cam_isp_hw_split_id split_id,
691 uint32_t subscribe_irq,
692 struct cam_isp_resource_node **wm_res,
693 uint32_t *client_done_mask)
694{
695 uint32_t wm_idx = 0;
696 struct cam_isp_resource_node *wm_res_local = NULL;
697 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
698
699 *wm_res = NULL;
700 *client_done_mask = 0;
701
702 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
703 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
704 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700705 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700706 vfe_out_res_id, plane);
707 return -EINVAL;
708 }
709
710 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700711 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700712 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
713
714 rsrc_data = wm_res_local->res_priv;
715 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700716 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700717 rsrc_data->format = out_port_info->format;
718 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
719
720 rsrc_data->width = out_port_info->width;
721 rsrc_data->height = out_port_info->height;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700722
723 if (rsrc_data->index < 3) {
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530724 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
725 rsrc_data->height = 0;
726 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
727 rsrc_data->pack_fmt = 0x0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700728 rsrc_data->en_cfg = 0x3;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530729 } else if (rsrc_data->index < 5 ||
730 rsrc_data->index == 7 || rsrc_data->index == 8) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700731 switch (plane) {
732 case PLANE_Y:
733 switch (rsrc_data->format) {
734 case CAM_FORMAT_UBWC_NV12:
735 case CAM_FORMAT_UBWC_NV12_4R:
736 case CAM_FORMAT_UBWC_TP10:
737 rsrc_data->en_ubwc = 1;
738 break;
739 default:
740 break;
741 }
742 break;
743 case PLANE_C:
744 switch (rsrc_data->format) {
745 case CAM_FORMAT_NV21:
746 case CAM_FORMAT_NV12:
747 rsrc_data->height /= 2;
748 break;
749 case CAM_FORMAT_UBWC_NV12:
750 case CAM_FORMAT_UBWC_NV12_4R:
751 case CAM_FORMAT_UBWC_TP10:
752 rsrc_data->height /= 2;
753 rsrc_data->en_ubwc = 1;
754 break;
755 default:
756 break;
757 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700758 break;
759 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700760 CAM_ERR(CAM_ISP, "Invalid plane type %d", plane);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700761 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700762 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700763 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530764 } else if (rsrc_data->index >= 11) {
765 rsrc_data->width = 0;
766 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530767 rsrc_data->stride = 1;
768 rsrc_data->en_cfg = 0x3;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700769 } else {
770 rsrc_data->width = rsrc_data->width * 4;
771 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700772 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700773 }
774
775 if (vfe_out_res_id >= CAM_ISP_IFE_OUT_RES_RDI_0 &&
776 vfe_out_res_id <= CAM_ISP_IFE_OUT_RES_RDI_3)
777 rsrc_data->frame_based = 1;
778
779 *client_done_mask = (1 << wm_idx);
780 *wm_res = wm_res_local;
781
782 return 0;
783}
784
785static int cam_vfe_bus_release_wm(void *bus_priv,
786 struct cam_isp_resource_node *wm_res)
787{
788 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
789 wm_res->res_priv;
790
791 rsrc_data->irq_enabled = 0;
792 rsrc_data->offset = 0;
793 rsrc_data->width = 0;
794 rsrc_data->height = 0;
795 rsrc_data->stride = 0;
796 rsrc_data->format = 0;
797 rsrc_data->pack_fmt = 0;
798 rsrc_data->burst_len = 0;
799 rsrc_data->frame_based = 0;
800 rsrc_data->irq_subsample_period = 0;
801 rsrc_data->irq_subsample_pattern = 0;
802 rsrc_data->framedrop_period = 0;
803 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700804 rsrc_data->packer_cfg = 0;
805 rsrc_data->en_ubwc = 0;
806 rsrc_data->tile_cfg = 0;
807 rsrc_data->h_init = 0;
808 rsrc_data->v_init = 0;
809 rsrc_data->ubwc_meta_stride = 0;
810 rsrc_data->ubwc_mode_cfg = 0;
811 rsrc_data->ubwc_meta_offset = 0;
812 rsrc_data->init_cfg_done = 0;
813 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700814
815 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700816 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
817
818 return 0;
819}
820
821static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
822{
823 int rc = 0;
824 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
825 wm_res->res_priv;
826 struct cam_vfe_bus_ver2_common_data *common_data =
827 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -0700828 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -0700829
Harsh Shah23557ae2017-05-13 18:14:34 -0700830 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
831 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -0700832 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
833
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700834 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -0700835 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700836 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -0700837 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700838 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -0700839 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700840
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530841 /* Configure stride for RDIs */
842 if (rsrc_data->index < 3)
843 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
844 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -0700845
Harsh Shah19f55812017-06-26 18:58:49 -0700846 /* Subscribe IRQ */
847 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700848 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -0700849 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
850 (1 << rsrc_data->index);
851 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
852 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
853 bus_irq_reg_mask, wm_res,
854 wm_res->top_half_handler,
855 cam_ife_mgr_do_tasklet_buf_done,
856 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
857 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700858 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -0700859 rsrc_data->index);
860 return -EFAULT;
861 }
862 }
863
Junzhe Zou3d292562017-07-12 17:59:58 -0700864 /* enable ubwc if needed*/
865 if (rsrc_data->en_ubwc) {
866 cam_io_w_mb(0x1, common_data->mem_base +
867 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
868 }
869
Harsh Shah19f55812017-06-26 18:58:49 -0700870 /* Enable WM */
871 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
872 rsrc_data->hw_regs->cfg);
873
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700874 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700875 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700876 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700877 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700878 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700879 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700880 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
881 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
882 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700883
884 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
885
886 return rc;
887}
888
889static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
890{
891 int rc = 0;
892 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
893 wm_res->res_priv;
894 struct cam_vfe_bus_ver2_common_data *common_data =
895 rsrc_data->common_data;
896
897 /* Disble WM */
898 cam_io_w_mb(0x0,
899 common_data->mem_base + rsrc_data->hw_regs->cfg);
900
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700901 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -0700902 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -0700903 if (rsrc_data->irq_enabled)
904 rc = cam_irq_controller_unsubscribe_irq(
905 common_data->bus_irq_controller,
906 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -0700907
908 /* Halt & Reset WM */
909 cam_io_w_mb(BIT(rsrc_data->index),
910 common_data->mem_base + common_data->common_reg->sw_reset);
911
912 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
913
914 return rc;
915}
916
917static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
918 struct cam_irq_th_payload *th_payload)
919{
Harsh Shah19f55812017-06-26 18:58:49 -0700920 int32_t rc;
921 int i;
922 struct cam_isp_resource_node *wm_res = NULL;
923 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
924 struct cam_vfe_bus_irq_evt_payload *evt_payload;
925
926 wm_res = th_payload->handler_priv;
927 if (!wm_res) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700928 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700929 return -ENODEV;
930 }
931
932 rsrc_data = wm_res->res_priv;
933
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700934 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
935 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -0700936
937 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
938 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700939 CAM_ERR_RATE_LIMIT(CAM_ISP,
940 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700941 return rc;
942 }
943
944 cam_isp_hw_get_timestamp(&evt_payload->ts);
945
946 evt_payload->ctx = rsrc_data->ctx;
947 evt_payload->core_index = rsrc_data->common_data->core_index;
948 evt_payload->evt_id = evt_id;
949
950 for (i = 0; i < th_payload->num_registers; i++)
951 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
952
953 th_payload->evt_payload_priv = evt_payload;
954
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700955 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -0700956 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -0700957}
958
959static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
960 void *evt_payload_priv)
961{
962 int rc = CAM_VFE_IRQ_STATUS_ERR;
963 struct cam_isp_resource_node *wm_res = wm_node;
964 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -0700965 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
966 (wm_res == NULL) ? NULL : wm_res->res_priv;
967 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -0700968 uint32_t status_reg;
969
Harsh Shah23557ae2017-05-13 18:14:34 -0700970 if (!evt_payload || !rsrc_data)
971 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -0700972
Harsh Shah23557ae2017-05-13 18:14:34 -0700973 cam_ife_irq_regs = evt_payload->irq_reg_val;
974 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
975
976 if (status_reg & BIT(rsrc_data->index)) {
977 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
978 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -0700979 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -0700980 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700981 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -0700982
983 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -0700984 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -0700985 &evt_payload);
986
987 return rc;
988}
989
990static int cam_vfe_bus_init_wm_resource(uint32_t index,
991 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
992 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
993 struct cam_isp_resource_node *wm_res)
994{
Harsh Shaha1af8822017-05-11 22:06:36 -0700995 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
996
997 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
998 GFP_KERNEL);
999 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001000 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001001 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001002 }
1003 wm_res->res_priv = rsrc_data;
1004
1005 rsrc_data->index = index;
1006 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1007 rsrc_data->common_data = &ver2_bus_priv->common_data;
1008
1009 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1010 INIT_LIST_HEAD(&wm_res->list);
1011
1012 wm_res->start = cam_vfe_bus_start_wm;
1013 wm_res->stop = cam_vfe_bus_stop_wm;
1014 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1015 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1016 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1017
Harsh Shah545df9a2017-06-16 16:43:17 -07001018 return 0;
1019}
1020
1021static int cam_vfe_bus_deinit_wm_resource(
1022 struct cam_isp_resource_node *wm_res)
1023{
1024 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1025
1026 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1027 INIT_LIST_HEAD(&wm_res->list);
1028
1029 wm_res->start = NULL;
1030 wm_res->stop = NULL;
1031 wm_res->top_half_handler = NULL;
1032 wm_res->bottom_half_handler = NULL;
1033 wm_res->hw_intf = NULL;
1034
1035 rsrc_data = wm_res->res_priv;
1036 wm_res->res_priv = NULL;
1037 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001038 CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001039 return -ENOMEM;
1040 }
1041 kfree(rsrc_data);
1042
1043 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001044}
1045
1046static void cam_vfe_bus_add_wm_to_comp_grp(
1047 struct cam_isp_resource_node *comp_grp,
1048 uint32_t composite_mask)
1049{
1050 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1051
1052 rsrc_data->composite_mask |= composite_mask;
1053}
1054
1055static void cam_vfe_bus_match_comp_grp(
1056 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1057 struct cam_isp_resource_node **comp_grp,
1058 uint32_t comp_grp_local_idx,
1059 uint32_t unique_id)
1060{
1061 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1062 struct cam_isp_resource_node *comp_grp_local = NULL;
1063
1064 list_for_each_entry(comp_grp_local,
1065 &ver2_bus_priv->used_comp_grp, list) {
1066 rsrc_data = comp_grp_local->res_priv;
1067 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1068 rsrc_data->unique_id == unique_id) {
1069 /* Match found */
1070 *comp_grp = comp_grp_local;
1071 return;
1072 }
1073 }
1074
1075 *comp_grp = NULL;
1076}
1077
1078static int cam_vfe_bus_acquire_comp_grp(
1079 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1080 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001081 void *tasklet,
1082 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001083 uint32_t unique_id,
1084 uint32_t is_dual,
1085 uint32_t is_master,
1086 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1087 struct cam_isp_resource_node **comp_grp)
1088{
1089 int rc = 0;
1090 struct cam_isp_resource_node *comp_grp_local = NULL;
1091 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1092
1093 /* Check if matching comp_grp already acquired */
1094 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1095 out_port_info->comp_grp_id, unique_id);
1096
1097 if (!comp_grp_local) {
1098 /* First find a free group */
1099 if (is_dual) {
1100 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001101 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001102 return -ENODEV;
1103 }
1104 comp_grp_local = list_first_entry(
1105 &ver2_bus_priv->free_dual_comp_grp,
1106 struct cam_isp_resource_node, list);
1107 rsrc_data = comp_grp_local->res_priv;
1108 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1109 dual_slave_core,
1110 comp_grp_local->hw_intf->hw_idx,
1111 &rsrc_data->intra_client_mask);
1112 } else {
1113 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001114 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001115 return -ENODEV;
1116 }
1117 comp_grp_local = list_first_entry(
1118 &ver2_bus_priv->free_comp_grp,
1119 struct cam_isp_resource_node, list);
1120 rsrc_data = comp_grp_local->res_priv;
1121 }
1122
1123 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001124 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001125 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1126
1127 rsrc_data->is_master = is_master;
1128 rsrc_data->composite_mask = 0;
1129 rsrc_data->unique_id = unique_id;
1130 rsrc_data->comp_grp_local_idx = out_port_info->comp_grp_id;
1131
1132 list_add_tail(&comp_grp_local->list,
1133 &ver2_bus_priv->used_comp_grp);
1134
1135 } else {
1136 rsrc_data = comp_grp_local->res_priv;
1137 /* Do not support runtime change in composite mask */
1138 if (comp_grp_local->res_state ==
1139 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001140 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001141 comp_grp_local->res_state,
1142 rsrc_data->comp_grp_type);
1143 return -EBUSY;
1144 }
1145 }
1146
Harsh Shah19f55812017-06-26 18:58:49 -07001147 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -07001148 *comp_grp = comp_grp_local;
1149
1150 return rc;
1151}
1152
1153static int cam_vfe_bus_release_comp_grp(
1154 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1155 struct cam_isp_resource_node *in_comp_grp)
1156{
1157 struct cam_isp_resource_node *comp_grp = NULL;
1158 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1159 int match_found = 0;
1160
1161 if (!in_comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001162 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_rsrc_data);
Harsh Shaha1af8822017-05-11 22:06:36 -07001163 return -EINVAL;
1164 }
1165
1166 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
1167 /* Already Released. Do Nothing */
1168 return 0;
1169 }
1170
1171 in_rsrc_data = in_comp_grp->res_priv;
1172
1173 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1174 if (comp_grp == in_comp_grp) {
1175 match_found = 1;
1176 break;
1177 }
1178 }
1179
1180 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001181 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001182 in_rsrc_data->comp_grp_type);
1183 return -ENODEV;
1184 }
1185
1186
1187 list_del(&comp_grp->list);
1188 if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1189 in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1190 list_add_tail(&comp_grp->list,
1191 &ver2_bus_priv->free_dual_comp_grp);
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001192 else if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1193 && in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
Harsh Shaha1af8822017-05-11 22:06:36 -07001194 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1195
Harsh Shaha1af8822017-05-11 22:06:36 -07001196 in_rsrc_data->unique_id = 0;
1197 in_rsrc_data->comp_grp_local_idx = 0;
1198 in_rsrc_data->composite_mask = 0;
1199 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1200
Harsh Shah19f55812017-06-26 18:58:49 -07001201 comp_grp->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001202 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1203
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001204 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001205}
1206
1207static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1208{
1209 int rc = 0;
1210 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1211 comp_grp->res_priv;
1212 struct cam_vfe_bus_ver2_common_data *common_data =
1213 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001214 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001215
1216 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1217 rsrc_data->hw_regs->comp_mask);
1218
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001219 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1220 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1221 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001222
1223 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1224 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1225 rsrc_data->is_master) {
1226 int dual_comp_grp = (rsrc_data->comp_grp_type -
1227 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1228 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1229 common_data->common_reg->dual_master_comp_cfg);
1230
1231 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1232 intra_client_en |=
1233 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1234
1235 cam_io_w_mb(intra_client_en, common_data->mem_base +
1236 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001237
1238 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1239 } else {
1240 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1241 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1242 (1 << (rsrc_data->comp_grp_type + 5));
1243 }
1244
1245 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001246 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001247 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1248 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1249 bus_irq_reg_mask, comp_grp,
1250 comp_grp->top_half_handler,
1251 cam_ife_mgr_do_tasklet_buf_done,
1252 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1253 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001254 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001255 rsrc_data->comp_grp_type);
1256 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001257 }
1258
1259 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001260
Harsh Shaha1af8822017-05-11 22:06:36 -07001261 return rc;
1262}
1263
1264static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1265{
1266 int rc = 0;
1267 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1268 comp_grp->res_priv;
1269 struct cam_vfe_bus_ver2_common_data *common_data =
1270 rsrc_data->common_data;
1271
1272 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001273 rc = cam_irq_controller_unsubscribe_irq(
1274 common_data->bus_irq_controller,
1275 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001276
1277 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1278 rsrc_data->hw_regs->comp_mask);
1279 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1280 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1281 rsrc_data->is_master) {
1282 int dual_comp_grp = (rsrc_data->comp_grp_type -
1283 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1284 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1285 common_data->common_reg->dual_master_comp_cfg);
1286
1287 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1288 intra_client_en &=
1289 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1290
1291 cam_io_w_mb(intra_client_en, common_data->mem_base +
1292 common_data->common_reg->dual_master_comp_cfg);
1293 }
1294
1295 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1296
1297 return rc;
1298}
1299
1300static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1301 struct cam_irq_th_payload *th_payload)
1302{
Harsh Shah19f55812017-06-26 18:58:49 -07001303 int32_t rc;
1304 int i;
1305 struct cam_isp_resource_node *comp_grp = NULL;
1306 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1307 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1308
1309 comp_grp = th_payload->handler_priv;
1310 if (!comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001311 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001312 return -ENODEV;
1313 }
1314
1315 rsrc_data = comp_grp->res_priv;
1316
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001317 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1318 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001319
1320 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1321 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001322 CAM_ERR_RATE_LIMIT(CAM_ISP,
1323 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001324 return rc;
1325 }
1326
1327 cam_isp_hw_get_timestamp(&evt_payload->ts);
1328
1329 evt_payload->ctx = rsrc_data->ctx;
1330 evt_payload->core_index = rsrc_data->common_data->core_index;
1331 evt_payload->evt_id = evt_id;
1332
1333 for (i = 0; i < th_payload->num_registers; i++)
1334 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1335
1336 th_payload->evt_payload_priv = evt_payload;
1337
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001338 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001339 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001340}
1341
1342static int cam_vfe_bus_handle_comp_done_bottom_half(
1343 void *handler_priv,
1344 void *evt_payload_priv)
1345{
1346 int rc = CAM_VFE_IRQ_STATUS_ERR;
1347 struct cam_isp_resource_node *comp_grp = handler_priv;
1348 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1349 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001350 uint32_t *cam_ife_irq_regs;
1351 uint32_t status_reg;
1352 uint32_t comp_err_reg;
1353 uint32_t comp_grp_id;
1354
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001355 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001356
Harsh Shah23557ae2017-05-13 18:14:34 -07001357 if (!evt_payload)
1358 return rc;
1359
1360 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001361
Harsh Shaha1af8822017-05-11 22:06:36 -07001362 switch (rsrc_data->comp_grp_type) {
1363 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1364 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1365 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1366 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1367 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1368 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001369 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001370 CAM_VFE_BUS_VER2_COMP_GRP_0);
1371
1372 /* Check for Regular composite error */
1373 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1374
1375 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1376 if ((status_reg & BIT(11)) &&
1377 (comp_err_reg & rsrc_data->composite_mask)) {
1378 /* Check for Regular composite error */
1379 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1380 break;
1381 }
1382
1383 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1384 /* Check for Regular composite Overwrite */
1385 if ((status_reg & BIT(12)) &&
1386 (comp_err_reg & rsrc_data->composite_mask)) {
1387 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1388 break;
1389 }
1390
Harsh Shah23557ae2017-05-13 18:14:34 -07001391 /* Regular Composite SUCCESS */
1392 if (status_reg & BIT(comp_grp_id + 5)) {
1393 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1394 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001395 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001396 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001397
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001398 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001399 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001400 break;
1401
1402 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1403 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1404 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1405 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1406 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1407 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001408 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001409 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1410
1411 /* Check for DUAL composite error */
1412 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1413
1414 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1415 if ((status_reg & BIT(6)) &&
1416 (comp_err_reg & rsrc_data->composite_mask)) {
1417 /* Check for DUAL composite error */
1418 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1419 break;
1420 }
1421
1422 /* Check for Dual composite Overwrite */
1423 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1424 if ((status_reg & BIT(7)) &&
1425 (comp_err_reg & rsrc_data->composite_mask)) {
1426 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1427 break;
1428 }
1429
Harsh Shah23557ae2017-05-13 18:14:34 -07001430 /* DUAL Composite SUCCESS */
1431 if (status_reg & BIT(comp_grp_id)) {
1432 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1433 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001434 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001435 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001436
1437 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001438 default:
1439 rc = CAM_VFE_IRQ_STATUS_ERR;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001440 CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001441 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001442 break;
1443 }
1444
1445 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001446 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001447 &evt_payload);
1448
1449 return rc;
1450}
1451
1452static int cam_vfe_bus_init_comp_grp(uint32_t index,
1453 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1454 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1455 struct cam_isp_resource_node *comp_grp)
1456{
Harsh Shah545df9a2017-06-16 16:43:17 -07001457 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001458
1459 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1460 GFP_KERNEL);
1461 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001462 CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001463 return -ENOMEM;
1464 }
1465 comp_grp->res_priv = rsrc_data;
1466
1467 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1468 INIT_LIST_HEAD(&comp_grp->list);
1469
1470 rsrc_data->comp_grp_type = index;
1471 rsrc_data->common_data = &ver2_bus_priv->common_data;
1472 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1473 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1474
Harsh Shaha1af8822017-05-11 22:06:36 -07001475 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1476 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1477 list_add_tail(&comp_grp->list,
1478 &ver2_bus_priv->free_dual_comp_grp);
1479 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1480 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1481 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1482
1483 comp_grp->start = cam_vfe_bus_start_comp_grp;
1484 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1485 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1486 comp_grp->bottom_half_handler =
1487 cam_vfe_bus_handle_comp_done_bottom_half;
1488 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1489
1490 return 0;
1491}
1492
Harsh Shah545df9a2017-06-16 16:43:17 -07001493static int cam_vfe_bus_deinit_comp_grp(
1494 struct cam_isp_resource_node *comp_grp)
1495{
1496 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1497 comp_grp->res_priv;
1498
1499 comp_grp->start = NULL;
1500 comp_grp->stop = NULL;
1501 comp_grp->top_half_handler = NULL;
1502 comp_grp->bottom_half_handler = NULL;
1503 comp_grp->hw_intf = NULL;
1504
1505 list_del_init(&comp_grp->list);
1506 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1507
1508 comp_grp->res_priv = NULL;
1509
1510 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001511 CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001512 return -ENODEV;
1513 }
1514 kfree(rsrc_data);
1515
1516 return 0;
1517}
1518
Harsh Shah19f55812017-06-26 18:58:49 -07001519static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1520 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001521{
1522 int rc = -ENODEV;
1523 int i;
1524 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1525 uint32_t format;
1526 uint32_t num_wm;
1527 uint32_t subscribe_irq;
1528 uint32_t client_done_mask;
1529 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1530 struct cam_vfe_acquire_args *acq_args = acquire_args;
1531 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1532 struct cam_isp_resource_node *rsrc_node = NULL;
1533 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1534
1535 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001536 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001537 return -EINVAL;
1538 }
1539
1540 out_acquire_args = &acq_args->vfe_out;
1541 format = out_acquire_args->out_port_info->format;
1542
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001543 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001544 out_acquire_args->out_port_info->res_type);
1545
1546 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1547 out_acquire_args->out_port_info->res_type);
1548 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1549 return -ENODEV;
1550
1551 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1552 if (num_wm < 1)
1553 return -EINVAL;
1554
1555 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1556 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001557 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001558 vfe_out_res_id, rsrc_node->res_state);
1559 return -EBUSY;
1560 }
1561
1562 rsrc_data = rsrc_node->res_priv;
1563 rsrc_data->num_wm = num_wm;
1564 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1565 rsrc_node->tasklet_info = acq_args->tasklet;
1566 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1567 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1568
1569 /* Reserve Composite Group */
1570 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1571 CAM_ISP_RES_COMP_GROUP_NONE &&
1572 out_acquire_args->out_port_info->comp_grp_id <
1573 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1574 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1575 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001576 acq_args->tasklet,
1577 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001578 out_acquire_args->unique_id,
1579 out_acquire_args->is_dual,
1580 out_acquire_args->is_master,
1581 out_acquire_args->dual_slave_core,
1582 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001583 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001584 CAM_ERR(CAM_ISP,
1585 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001586 rsrc_data->common_data->core_index,
1587 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001588 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001589 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001590
1591 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001592 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001593 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001594 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001595
1596 /* Reserve WM */
1597 for (i = 0; i < num_wm; i++) {
1598 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1599 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001600 acq_args->tasklet,
1601 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001602 vfe_out_res_id,
1603 i,
1604 out_acquire_args->split_id,
1605 subscribe_irq,
1606 &rsrc_data->wm_res[i],
1607 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001608 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001609 CAM_ERR(CAM_ISP,
1610 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001611 rsrc_data->common_data->core_index,
1612 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001613 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001614 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001615
1616 if (rsrc_data->comp_grp)
1617 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1618 client_done_mask);
1619 }
1620
1621 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1622 out_acquire_args->rsrc_node = rsrc_node;
1623
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001624 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001625 return rc;
1626
1627release_wm:
1628 for (i--; i >= 0; i--)
1629 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1630
1631 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1632 rsrc_data->comp_grp);
1633
1634 return rc;
1635}
1636
Harsh Shah19f55812017-06-26 18:58:49 -07001637static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1638 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001639{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001640 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001641 struct cam_isp_resource_node *vfe_out = NULL;
1642 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1643
1644 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001645 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001646 bus_priv, release_args);
1647 return -EINVAL;
1648 }
1649
1650 vfe_out = release_args;
1651 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001652
Harsh Shaha1af8822017-05-11 22:06:36 -07001653 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001654 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001655 vfe_out->res_state);
1656 }
1657
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001658 for (i = 0; i < rsrc_data->num_wm; i++)
1659 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1660 rsrc_data->num_wm = 0;
1661
1662 if (rsrc_data->comp_grp)
1663 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1664 rsrc_data->comp_grp = NULL;
1665
1666 vfe_out->tasklet_info = NULL;
1667 vfe_out->cdm_ops = NULL;
1668 rsrc_data->cdm_util_ops = NULL;
1669
Harsh Shaha1af8822017-05-11 22:06:36 -07001670 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1671 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1672
1673 return 0;
1674}
1675
Harsh Shah19f55812017-06-26 18:58:49 -07001676static int cam_vfe_bus_start_vfe_out(
1677 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001678{
1679 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001680 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1681 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1682
1683 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001684 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001685 return -EINVAL;
1686 }
1687
1688 rsrc_data = vfe_out->res_priv;
1689 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001690
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001691 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001692
1693 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001694 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001695 vfe_out->res_state);
1696 return -EACCES;
1697 }
1698
1699 for (i = 0; i < rsrc_data->num_wm; i++)
1700 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1701
1702 if (rsrc_data->comp_grp)
1703 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1704
Harsh Shaha1af8822017-05-11 22:06:36 -07001705 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1706 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1707 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1708 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1709 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1710 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001711 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1712 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1713 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1714 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1715 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1716 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1717 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1718 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1719 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1720
Harsh Shah23557ae2017-05-13 18:14:34 -07001721 /* no clock gating at bus input */
1722 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1723
1724 /* BUS_WR_TEST_BUS_CTRL */
1725 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
1726
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05301727 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07001728 return rc;
1729}
1730
Harsh Shah19f55812017-06-26 18:58:49 -07001731static int cam_vfe_bus_stop_vfe_out(
1732 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001733{
1734 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001735 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1736
1737 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001738 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001739 return -EINVAL;
1740 }
1741
1742 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001743
1744 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
1745 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
1746 return rc;
1747 }
1748
1749 if (rsrc_data->comp_grp)
1750 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
1751
1752 for (i = 0; i < rsrc_data->num_wm; i++)
1753 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
1754
Harsh Shaha1af8822017-05-11 22:06:36 -07001755
1756 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1757 return rc;
1758}
1759
1760static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
1761 struct cam_irq_th_payload *th_payload)
1762{
1763 return -EPERM;
1764}
1765
1766static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
1767 void *handler_priv,
1768 void *evt_payload_priv)
1769{
1770 int rc = -EINVAL;
1771 struct cam_isp_resource_node *vfe_out = handler_priv;
1772 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1773
1774 /*
1775 * If this resource has Composite Group then we only handle
1776 * Composite done. We acquire Composite if number of WM > 1.
1777 * So Else case is only one individual buf_done = WM[0].
1778 */
1779 if (rsrc_data->comp_grp) {
1780 rc = rsrc_data->comp_grp->bottom_half_handler(
1781 rsrc_data->comp_grp, evt_payload_priv);
1782 } else {
1783 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07001784 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07001785 }
1786
1787 return rc;
1788}
1789
1790static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
1791 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1792 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1793 struct cam_isp_resource_node *vfe_out)
1794{
1795 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1796 int rc = 0;
1797
1798 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
1799 GFP_KERNEL);
1800 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001801 CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001802 rc = -ENOMEM;
1803 return rc;
1804 }
1805 vfe_out->res_priv = rsrc_data;
1806
1807 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
1808 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1809 INIT_LIST_HEAD(&vfe_out->list);
1810
1811 rsrc_data->out_type = index;
1812 rsrc_data->common_data = &ver2_bus_priv->common_data;
1813 rsrc_data->max_width =
1814 ver2_hw_info->vfe_out_hw_info[index].max_width;
1815 rsrc_data->max_height =
1816 ver2_hw_info->vfe_out_hw_info[index].max_height;
1817
1818 vfe_out->start = cam_vfe_bus_start_vfe_out;
1819 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
1820 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
1821 vfe_out->bottom_half_handler =
1822 cam_vfe_bus_handle_vfe_out_done_bottom_half;
1823 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
1824
1825 return 0;
1826}
1827
Harsh Shah545df9a2017-06-16 16:43:17 -07001828static int cam_vfe_bus_deinit_vfe_out_resource(
1829 struct cam_isp_resource_node *vfe_out)
1830{
1831 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1832
1833 vfe_out->start = NULL;
1834 vfe_out->stop = NULL;
1835 vfe_out->top_half_handler = NULL;
1836 vfe_out->bottom_half_handler = NULL;
1837 vfe_out->hw_intf = NULL;
1838
1839 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1840 INIT_LIST_HEAD(&vfe_out->list);
1841 vfe_out->res_priv = NULL;
1842
1843 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001844 CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001845 return -ENOMEM;
1846 }
1847 kfree(rsrc_data);
1848
1849 return 0;
1850}
1851
Harsh Shaha1af8822017-05-11 22:06:36 -07001852static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
1853 struct cam_irq_th_payload *th_payload)
1854{
Harsh Shaha1af8822017-05-11 22:06:36 -07001855 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001856
Harsh Shah19f55812017-06-26 18:58:49 -07001857 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001858 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07001859 return cam_irq_controller_handle_irq(evt_id,
1860 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07001861}
1862
1863static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
1864 uint32_t arg_size)
1865{
1866 struct cam_vfe_bus_ver2_priv *bus_priv;
1867 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001868 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07001869 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
1870 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001871 uint32_t *reg_val_pair;
1872 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07001873 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001874
1875 /*
1876 * Need the entire buf io config so we can get the stride info
1877 * for the wm.
1878 */
1879
1880 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
1881 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
1882
1883 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
1884 update_buf->cdm.res->res_priv;
1885
1886 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001887 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07001888 return -EINVAL;
1889 }
1890
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001891 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001892 CAM_ERR(CAM_ISP,
1893 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001894 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07001895 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001896 }
1897
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001898 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
1899 io_cfg = update_buf->io_cfg;
1900
1901 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07001902 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001903 CAM_ERR(CAM_ISP,
1904 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07001905 j, MAX_REG_VAL_PAIR_SIZE);
1906 return -ENOMEM;
1907 }
1908
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001909 wm_data = vfe_out_data->wm_res[i]->res_priv;
1910
1911 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301912 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
1913 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001914 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1915 wm_data->hw_regs->stride,
1916 io_cfg->planes[i].plane_stride);
1917 wm_data->stride = io_cfg->planes[i].plane_stride;
1918 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001919 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001920
1921 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
1922 !wm_data->init_cfg_done) {
1923 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1924 wm_data->hw_regs->framedrop_pattern,
1925 io_cfg->framedrop_pattern);
1926 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
1927 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001928 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
1929 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001930
1931 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
1932 !wm_data->init_cfg_done) {
1933 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1934 wm_data->hw_regs->framedrop_period,
1935 io_cfg->framedrop_period);
1936 wm_data->framedrop_period = io_cfg->framedrop_period;
1937 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001938 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
1939 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001940
1941 if (wm_data->irq_subsample_period != io_cfg->subsample_period
1942 || !wm_data->init_cfg_done) {
1943 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1944 wm_data->hw_regs->irq_subsample_period,
1945 io_cfg->subsample_period);
1946 wm_data->irq_subsample_period =
1947 io_cfg->subsample_period;
1948 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001949 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001950 wm_data->irq_subsample_period);
1951
1952 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
1953 || !wm_data->init_cfg_done) {
1954 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1955 wm_data->hw_regs->irq_subsample_pattern,
1956 io_cfg->subsample_pattern);
1957 wm_data->irq_subsample_pattern =
1958 io_cfg->subsample_pattern;
1959 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001960 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001961 wm_data->irq_subsample_pattern);
1962
1963 if (wm_data->en_ubwc) {
1964 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001965 CAM_ERR(CAM_ISP,
1966 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001967 return -EINVAL;
1968 }
1969 if (wm_data->packer_cfg !=
1970 io_cfg->planes[i].packer_config ||
1971 !wm_data->init_cfg_done) {
1972 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1973 wm_data->hw_regs->packer_cfg,
1974 io_cfg->planes[i].packer_config);
1975 wm_data->packer_cfg =
1976 io_cfg->planes[i].packer_config;
1977 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001978 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
1979 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001980
1981 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
1982 || !wm_data->init_cfg_done) {
1983 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1984 wm_data->hw_regs->ubwc_regs->tile_cfg,
1985 io_cfg->planes[i].tile_config);
1986 wm_data->tile_cfg =
1987 io_cfg->planes[i].tile_config;
1988 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001989 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001990
1991 if (wm_data->h_init != io_cfg->planes[i].h_init ||
1992 !wm_data->init_cfg_done) {
1993 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1994 wm_data->hw_regs->ubwc_regs->h_init,
1995 io_cfg->planes[i].h_init);
1996 wm_data->h_init = io_cfg->planes[i].h_init;
1997 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001998 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001999
2000 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2001 !wm_data->init_cfg_done) {
2002 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2003 wm_data->hw_regs->ubwc_regs->v_init,
2004 io_cfg->planes[i].v_init);
2005 wm_data->v_init = io_cfg->planes[i].v_init;
2006 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002007 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002008
2009 if (wm_data->ubwc_meta_stride !=
2010 io_cfg->planes[i].meta_stride ||
2011 !wm_data->init_cfg_done) {
2012 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2013 wm_data->hw_regs->ubwc_regs->
2014 meta_stride,
2015 io_cfg->planes[i].meta_stride);
2016 wm_data->ubwc_meta_stride =
2017 io_cfg->planes[i].meta_stride;
2018 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002019 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2020 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002021
2022 if (wm_data->ubwc_mode_cfg !=
2023 io_cfg->planes[i].mode_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->mode_cfg,
2027 io_cfg->planes[i].mode_config);
2028 wm_data->ubwc_mode_cfg =
2029 io_cfg->planes[i].mode_config;
2030 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002031 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2032 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002033
2034 if (wm_data->ubwc_meta_offset !=
2035 io_cfg->planes[i].meta_offset ||
2036 !wm_data->init_cfg_done) {
2037 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2038 wm_data->hw_regs->ubwc_regs->
2039 meta_offset,
2040 io_cfg->planes[i].meta_offset);
2041 wm_data->ubwc_meta_offset =
2042 io_cfg->planes[i].meta_offset;
2043 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002044 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002045 wm_data->ubwc_meta_offset);
2046
2047 /* UBWC meta address */
2048 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2049 wm_data->hw_regs->ubwc_regs->meta_addr,
2050 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002051 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002052 update_buf->image_buf[i]);
2053 }
2054
2055 /* WM Image address */
2056 if (wm_data->en_ubwc)
2057 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2058 wm_data->hw_regs->image_addr,
2059 (update_buf->image_buf[i] +
2060 io_cfg->planes[i].meta_size));
2061 else
2062 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2063 wm_data->hw_regs->image_addr,
2064 update_buf->image_buf[i]);
2065
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002066 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002067
Junzhe Zou193d78c2017-05-16 15:10:54 -07002068 frame_inc = io_cfg->planes[i].plane_stride *
2069 io_cfg->planes[i].slice_height;
2070 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2071 wm_data->hw_regs->frame_inc, frame_inc);
2072
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002073 /* enable the WM */
2074 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2075 wm_data->hw_regs->cfg,
2076 wm_data->en_cfg);
2077
2078 /* set initial configuration done */
2079 if (!wm_data->init_cfg_done)
2080 wm_data->init_cfg_done = 1;
2081 }
2082
2083 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002084
2085 /* cdm util returns dwords, need to convert to bytes */
2086 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002087 CAM_ERR(CAM_ISP,
2088 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002089 update_buf->cdm.size, size);
2090 return -ENOMEM;
2091 }
2092
Harsh Shaha1af8822017-05-11 22:06:36 -07002093 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002094 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2095
Harsh Shaha1af8822017-05-11 22:06:36 -07002096 /* cdm util returns dwords, need to convert to bytes */
2097 update_buf->cdm.used_bytes = size * 4;
2098
2099 return 0;
2100}
2101
Harsh Shah19f55812017-06-26 18:58:49 -07002102static int cam_vfe_bus_start_hw(void *hw_priv,
2103 void *start_hw_args, uint32_t arg_size)
2104{
2105 return cam_vfe_bus_start_vfe_out(hw_priv);
2106}
2107
2108static int cam_vfe_bus_stop_hw(void *hw_priv,
2109 void *stop_hw_args, uint32_t arg_size)
2110{
2111 return cam_vfe_bus_stop_vfe_out(hw_priv);
2112}
2113
2114static int cam_vfe_bus_init_hw(void *hw_priv,
2115 void *init_hw_args, uint32_t arg_size)
2116{
2117 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2118 uint32_t top_irq_reg_mask[2] = {0};
2119
2120 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002121 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002122 return -EINVAL;
2123 }
2124
2125 top_irq_reg_mask[0] = (1 << 9);
2126
2127 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2128 bus_priv->common_data.vfe_irq_controller,
2129 CAM_IRQ_PRIORITY_2,
2130 top_irq_reg_mask,
2131 bus_priv,
2132 cam_vfe_bus_ver2_handle_irq,
2133 NULL,
2134 NULL,
2135 NULL);
2136
2137 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002138 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002139 return -EFAULT;
2140 }
2141
2142 return 0;
2143}
2144
2145static int cam_vfe_bus_deinit_hw(void *hw_priv,
2146 void *deinit_hw_args, uint32_t arg_size)
2147{
2148 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2149 int rc;
2150
2151 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002152 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002153 return -EINVAL;
2154 }
2155
2156 rc = cam_irq_controller_unsubscribe_irq(
2157 bus_priv->common_data.vfe_irq_controller,
2158 bus_priv->irq_handle);
2159 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002160 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002161
2162 return rc;
2163}
2164
Harsh Shaha1af8822017-05-11 22:06:36 -07002165static int cam_vfe_bus_process_cmd(void *priv,
2166 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2167{
2168 int rc = -EINVAL;
2169
2170 if (!priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002171 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
Harsh Shaha1af8822017-05-11 22:06:36 -07002172 return -EINVAL;
2173 }
2174
2175 switch (cmd_type) {
2176 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2177 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2178 break;
2179 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002180 CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
Harsh Shaha1af8822017-05-11 22:06:36 -07002181 cmd_type);
2182 break;
2183 }
2184
2185 return rc;
2186}
2187
2188int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002189 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002190 struct cam_hw_intf *hw_intf,
2191 void *bus_hw_info,
2192 void *vfe_irq_controller,
2193 struct cam_vfe_bus **vfe_bus)
2194{
2195 int i, rc = 0;
2196 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2197 struct cam_vfe_bus *vfe_bus_local;
2198 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2199
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002200 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002201
Harsh Shah19f55812017-06-26 18:58:49 -07002202 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002203 CAM_ERR(CAM_ISP,
2204 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2205 soc_info, hw_intf, bus_hw_info);
2206 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002207 rc = -EINVAL;
2208 goto end;
2209 }
2210
Harsh Shaha1af8822017-05-11 22:06:36 -07002211 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2212 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002213 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002214 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002215 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002216 }
2217
2218 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2219 GFP_KERNEL);
2220 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002221 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002222 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002223 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002224 }
2225 vfe_bus_local->bus_priv = bus_priv;
2226
Harsh Shah19f55812017-06-26 18:58:49 -07002227 bus_priv->common_data.core_index = soc_info->index;
2228 bus_priv->common_data.mem_base =
2229 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002230 bus_priv->common_data.hw_intf = hw_intf;
2231 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2232 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
2233
Harsh Shah19f55812017-06-26 18:58:49 -07002234 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2235 &ver2_hw_info->common_reg.irq_reg_info,
2236 &bus_priv->common_data.bus_irq_controller);
2237 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002238 CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002239 goto free_bus_priv;
2240 }
2241
Harsh Shaha1af8822017-05-11 22:06:36 -07002242 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2243 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2244 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2245
2246 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2247 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2248 &bus_priv->bus_client[i]);
2249 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002250 CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002251 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002252 }
2253 }
2254
2255 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2256 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2257 &bus_priv->comp_grp[i]);
2258 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002259 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002260 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002261 }
2262 }
2263
2264 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2265 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2266 &bus_priv->vfe_out[i]);
2267 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002268 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002269 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002270 }
2271 }
2272
Harsh Shah19f55812017-06-26 18:58:49 -07002273 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2274 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2275 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2276 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2277 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002278 }
2279
Harsh Shah19f55812017-06-26 18:58:49 -07002280 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2281 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2282 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2283 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2284 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2285 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2286 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002287 vfe_bus_local->bottom_half_handler = NULL;
Harsh Shah19f55812017-06-26 18:58:49 -07002288 vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002289
2290 *vfe_bus = vfe_bus_local;
2291
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002292 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002293 return rc;
2294
Harsh Shah545df9a2017-06-16 16:43:17 -07002295deinit_vfe_out:
2296 if (i < 0)
2297 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2298 for (--i; i >= 0; i--)
2299 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2300
2301deinit_comp_grp:
2302 if (i < 0)
2303 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2304 for (--i; i >= 0; i--)
2305 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2306
2307deinit_wm:
2308 if (i < 0)
2309 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2310 for (--i; i >= 0; i--)
2311 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2312
Harsh Shah19f55812017-06-26 18:58:49 -07002313free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002314 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002315
2316free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002317 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002318
2319end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002320 return rc;
2321}
Harsh Shah545df9a2017-06-16 16:43:17 -07002322
2323int cam_vfe_bus_ver2_deinit(
2324 struct cam_vfe_bus **vfe_bus)
2325{
2326 int i, rc = 0;
2327 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2328 struct cam_vfe_bus *vfe_bus_local;
2329
2330 if (!vfe_bus || !*vfe_bus) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002331 CAM_ERR(CAM_ISP, "Error! Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002332 return -EINVAL;
2333 }
2334 vfe_bus_local = *vfe_bus;
2335
2336 bus_priv = vfe_bus_local->bus_priv;
2337 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002338 CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002339 rc = -ENODEV;
2340 goto free_bus_local;
2341 }
2342
Harsh Shah19f55812017-06-26 18:58:49 -07002343 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2344 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2345 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002346
2347 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2348 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2349 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002350 CAM_ERR(CAM_ISP,
2351 "Error! Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002352 }
2353
2354 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2355 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2356 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002357 CAM_ERR(CAM_ISP,
2358 "Error! Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002359 }
2360
2361 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2362 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2363 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002364 CAM_ERR(CAM_ISP,
2365 "Error! Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002366 }
2367
2368 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2369 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2370 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2371
Harsh Shah19f55812017-06-26 18:58:49 -07002372 rc = cam_irq_controller_deinit(
2373 &bus_priv->common_data.bus_irq_controller);
2374 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002375 CAM_ERR(CAM_ISP,
2376 "Error! Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002377
Harsh Shah545df9a2017-06-16 16:43:17 -07002378 kfree(vfe_bus_local->bus_priv);
2379
2380free_bus_local:
2381 kfree(vfe_bus_local);
2382
2383 *vfe_bus = NULL;
2384
2385 return rc;
2386}
2387