blob: 5d7a1b9fe5fa4a518596a49aafeb51d92cf6f1dc [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:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700653 case CAM_FORMAT_UBWC_NV12:
654 case CAM_FORMAT_UBWC_NV12_4R:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530655 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530656 case CAM_FORMAT_PLAIN64:
657 return PACKER_FMT_PLAIN_64;
658 case CAM_FORMAT_MIPI_RAW_6:
659 case CAM_FORMAT_MIPI_RAW_8:
660 case CAM_FORMAT_MIPI_RAW_10:
661 case CAM_FORMAT_MIPI_RAW_12:
662 case CAM_FORMAT_MIPI_RAW_14:
663 case CAM_FORMAT_MIPI_RAW_16:
664 case CAM_FORMAT_MIPI_RAW_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530665 case CAM_FORMAT_PLAIN128:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530666 case CAM_FORMAT_PLAIN8:
667 case CAM_FORMAT_PLAIN16_8:
668 case CAM_FORMAT_PLAIN16_10:
669 case CAM_FORMAT_PLAIN16_12:
670 case CAM_FORMAT_PLAIN16_14:
671 case CAM_FORMAT_PLAIN16_16:
672 case CAM_FORMAT_PLAIN32_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530673 case CAM_FORMAT_PD8:
674 case CAM_FORMAT_PD10:
675 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700676 case CAM_FORMAT_UBWC_TP10:
677 case CAM_FORMAT_TP10:
678 return PACKER_FMT_TP_10;
Harsh Shaha1af8822017-05-11 22:06:36 -0700679 default:
680 return PACKER_FMT_MAX;
681 }
682}
683
684static int cam_vfe_bus_acquire_wm(
685 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
686 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700687 void *tasklet,
688 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700689 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
690 enum cam_vfe_bus_plane_type plane,
691 enum cam_isp_hw_split_id split_id,
692 uint32_t subscribe_irq,
693 struct cam_isp_resource_node **wm_res,
694 uint32_t *client_done_mask)
695{
696 uint32_t wm_idx = 0;
697 struct cam_isp_resource_node *wm_res_local = NULL;
698 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
699
700 *wm_res = NULL;
701 *client_done_mask = 0;
702
703 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
704 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
705 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700706 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700707 vfe_out_res_id, plane);
708 return -EINVAL;
709 }
710
711 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700712 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700713 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
714
715 rsrc_data = wm_res_local->res_priv;
716 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700717 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700718 rsrc_data->format = out_port_info->format;
719 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
720
721 rsrc_data->width = out_port_info->width;
722 rsrc_data->height = out_port_info->height;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700723
724 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700725 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530726 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
727 rsrc_data->height = 0;
728 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
729 rsrc_data->pack_fmt = 0x0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700730 rsrc_data->en_cfg = 0x3;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530731 } else if (rsrc_data->index < 5 ||
732 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700733 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
734 switch (rsrc_data->format) {
735 case CAM_FORMAT_UBWC_NV12:
736 case CAM_FORMAT_UBWC_NV12_4R:
737 rsrc_data->en_ubwc = 1;
738 /* Fall through for NV12 */
739 case CAM_FORMAT_NV21:
740 case CAM_FORMAT_NV12:
741 switch (plane) {
742 case PLANE_C:
743 rsrc_data->height /= 2;
744 break;
745 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700746 break;
747 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700748 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
749 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700750 }
751 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700752 case CAM_FORMAT_UBWC_TP10:
753 rsrc_data->en_ubwc = 1;
754 /* Fall through for LINEAR TP10 */
755 case CAM_FORMAT_TP10:
756 rsrc_data->width = rsrc_data->width * 4 / 3;
757 switch (plane) {
758 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700759 rsrc_data->height /= 2;
760 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700761 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700762 break;
763 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700764 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
765 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700766 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700767 break;
768 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700769 CAM_ERR(CAM_ISP, "Invalid format %d\n",
770 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700771 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700772 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700773 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530774 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700775 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530776 rsrc_data->width = 0;
777 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530778 rsrc_data->stride = 1;
779 rsrc_data->en_cfg = 0x3;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700780 } else {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700781 /* Write master 5-6 DS ports , 9 - Raw dump , 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700782 rsrc_data->width = rsrc_data->width * 4;
783 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700784 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700785 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700786 if (vfe_out_res_id >= CAM_ISP_IFE_OUT_RES_RDI_0 &&
787 vfe_out_res_id <= CAM_ISP_IFE_OUT_RES_RDI_3)
788 rsrc_data->frame_based = 1;
789
790 *client_done_mask = (1 << wm_idx);
791 *wm_res = wm_res_local;
792
793 return 0;
794}
795
796static int cam_vfe_bus_release_wm(void *bus_priv,
797 struct cam_isp_resource_node *wm_res)
798{
799 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
800 wm_res->res_priv;
801
802 rsrc_data->irq_enabled = 0;
803 rsrc_data->offset = 0;
804 rsrc_data->width = 0;
805 rsrc_data->height = 0;
806 rsrc_data->stride = 0;
807 rsrc_data->format = 0;
808 rsrc_data->pack_fmt = 0;
809 rsrc_data->burst_len = 0;
810 rsrc_data->frame_based = 0;
811 rsrc_data->irq_subsample_period = 0;
812 rsrc_data->irq_subsample_pattern = 0;
813 rsrc_data->framedrop_period = 0;
814 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700815 rsrc_data->packer_cfg = 0;
816 rsrc_data->en_ubwc = 0;
817 rsrc_data->tile_cfg = 0;
818 rsrc_data->h_init = 0;
819 rsrc_data->v_init = 0;
820 rsrc_data->ubwc_meta_stride = 0;
821 rsrc_data->ubwc_mode_cfg = 0;
822 rsrc_data->ubwc_meta_offset = 0;
823 rsrc_data->init_cfg_done = 0;
824 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700825
826 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700827 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
828
829 return 0;
830}
831
832static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
833{
834 int rc = 0;
835 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
836 wm_res->res_priv;
837 struct cam_vfe_bus_ver2_common_data *common_data =
838 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -0700839 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -0700840
Harsh Shah23557ae2017-05-13 18:14:34 -0700841 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
842 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -0700843 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
844
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700845 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -0700846 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700847 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -0700848 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700849 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -0700850 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700851
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530852 /* Configure stride for RDIs */
853 if (rsrc_data->index < 3)
854 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
855 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -0700856
Harsh Shah19f55812017-06-26 18:58:49 -0700857 /* Subscribe IRQ */
858 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700859 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -0700860 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
861 (1 << rsrc_data->index);
862 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
863 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
864 bus_irq_reg_mask, wm_res,
865 wm_res->top_half_handler,
866 cam_ife_mgr_do_tasklet_buf_done,
867 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
868 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700869 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -0700870 rsrc_data->index);
871 return -EFAULT;
872 }
873 }
874
Junzhe Zou3d292562017-07-12 17:59:58 -0700875 /* enable ubwc if needed*/
876 if (rsrc_data->en_ubwc) {
877 cam_io_w_mb(0x1, common_data->mem_base +
878 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
879 }
880
Harsh Shah19f55812017-06-26 18:58:49 -0700881 /* Enable WM */
882 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
883 rsrc_data->hw_regs->cfg);
884
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700885 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700886 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700887 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700888 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700889 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700890 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700891 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
892 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
893 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700894
895 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
896
897 return rc;
898}
899
900static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
901{
902 int rc = 0;
903 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
904 wm_res->res_priv;
905 struct cam_vfe_bus_ver2_common_data *common_data =
906 rsrc_data->common_data;
907
908 /* Disble WM */
909 cam_io_w_mb(0x0,
910 common_data->mem_base + rsrc_data->hw_regs->cfg);
911
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700912 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -0700913 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -0700914 if (rsrc_data->irq_enabled)
915 rc = cam_irq_controller_unsubscribe_irq(
916 common_data->bus_irq_controller,
917 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -0700918
919 /* Halt & Reset WM */
920 cam_io_w_mb(BIT(rsrc_data->index),
921 common_data->mem_base + common_data->common_reg->sw_reset);
922
923 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
924
925 return rc;
926}
927
928static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
929 struct cam_irq_th_payload *th_payload)
930{
Harsh Shah19f55812017-06-26 18:58:49 -0700931 int32_t rc;
932 int i;
933 struct cam_isp_resource_node *wm_res = NULL;
934 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
935 struct cam_vfe_bus_irq_evt_payload *evt_payload;
936
937 wm_res = th_payload->handler_priv;
938 if (!wm_res) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700939 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700940 return -ENODEV;
941 }
942
943 rsrc_data = wm_res->res_priv;
944
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700945 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
946 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -0700947
948 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
949 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700950 CAM_ERR_RATE_LIMIT(CAM_ISP,
951 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -0700952 return rc;
953 }
954
955 cam_isp_hw_get_timestamp(&evt_payload->ts);
956
957 evt_payload->ctx = rsrc_data->ctx;
958 evt_payload->core_index = rsrc_data->common_data->core_index;
959 evt_payload->evt_id = evt_id;
960
961 for (i = 0; i < th_payload->num_registers; i++)
962 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
963
964 th_payload->evt_payload_priv = evt_payload;
965
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700966 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -0700967 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -0700968}
969
970static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
971 void *evt_payload_priv)
972{
973 int rc = CAM_VFE_IRQ_STATUS_ERR;
974 struct cam_isp_resource_node *wm_res = wm_node;
975 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -0700976 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
977 (wm_res == NULL) ? NULL : wm_res->res_priv;
978 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -0700979 uint32_t status_reg;
980
Harsh Shah23557ae2017-05-13 18:14:34 -0700981 if (!evt_payload || !rsrc_data)
982 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -0700983
Harsh Shah23557ae2017-05-13 18:14:34 -0700984 cam_ife_irq_regs = evt_payload->irq_reg_val;
985 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
986
987 if (status_reg & BIT(rsrc_data->index)) {
988 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
989 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -0700990 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -0700991 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700992 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -0700993
994 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -0700995 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -0700996 &evt_payload);
997
998 return rc;
999}
1000
1001static int cam_vfe_bus_init_wm_resource(uint32_t index,
1002 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1003 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1004 struct cam_isp_resource_node *wm_res)
1005{
Harsh Shaha1af8822017-05-11 22:06:36 -07001006 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1007
1008 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1009 GFP_KERNEL);
1010 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001011 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001012 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001013 }
1014 wm_res->res_priv = rsrc_data;
1015
1016 rsrc_data->index = index;
1017 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1018 rsrc_data->common_data = &ver2_bus_priv->common_data;
1019
1020 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1021 INIT_LIST_HEAD(&wm_res->list);
1022
1023 wm_res->start = cam_vfe_bus_start_wm;
1024 wm_res->stop = cam_vfe_bus_stop_wm;
1025 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1026 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1027 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1028
Harsh Shah545df9a2017-06-16 16:43:17 -07001029 return 0;
1030}
1031
1032static int cam_vfe_bus_deinit_wm_resource(
1033 struct cam_isp_resource_node *wm_res)
1034{
1035 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1036
1037 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1038 INIT_LIST_HEAD(&wm_res->list);
1039
1040 wm_res->start = NULL;
1041 wm_res->stop = NULL;
1042 wm_res->top_half_handler = NULL;
1043 wm_res->bottom_half_handler = NULL;
1044 wm_res->hw_intf = NULL;
1045
1046 rsrc_data = wm_res->res_priv;
1047 wm_res->res_priv = NULL;
1048 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001049 CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001050 return -ENOMEM;
1051 }
1052 kfree(rsrc_data);
1053
1054 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001055}
1056
1057static void cam_vfe_bus_add_wm_to_comp_grp(
1058 struct cam_isp_resource_node *comp_grp,
1059 uint32_t composite_mask)
1060{
1061 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1062
1063 rsrc_data->composite_mask |= composite_mask;
1064}
1065
1066static void cam_vfe_bus_match_comp_grp(
1067 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1068 struct cam_isp_resource_node **comp_grp,
1069 uint32_t comp_grp_local_idx,
1070 uint32_t unique_id)
1071{
1072 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1073 struct cam_isp_resource_node *comp_grp_local = NULL;
1074
1075 list_for_each_entry(comp_grp_local,
1076 &ver2_bus_priv->used_comp_grp, list) {
1077 rsrc_data = comp_grp_local->res_priv;
1078 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1079 rsrc_data->unique_id == unique_id) {
1080 /* Match found */
1081 *comp_grp = comp_grp_local;
1082 return;
1083 }
1084 }
1085
1086 *comp_grp = NULL;
1087}
1088
1089static int cam_vfe_bus_acquire_comp_grp(
1090 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1091 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001092 void *tasklet,
1093 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001094 uint32_t unique_id,
1095 uint32_t is_dual,
1096 uint32_t is_master,
1097 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1098 struct cam_isp_resource_node **comp_grp)
1099{
1100 int rc = 0;
1101 struct cam_isp_resource_node *comp_grp_local = NULL;
1102 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1103
1104 /* Check if matching comp_grp already acquired */
1105 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1106 out_port_info->comp_grp_id, unique_id);
1107
1108 if (!comp_grp_local) {
1109 /* First find a free group */
1110 if (is_dual) {
1111 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001112 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001113 return -ENODEV;
1114 }
1115 comp_grp_local = list_first_entry(
1116 &ver2_bus_priv->free_dual_comp_grp,
1117 struct cam_isp_resource_node, list);
1118 rsrc_data = comp_grp_local->res_priv;
1119 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1120 dual_slave_core,
1121 comp_grp_local->hw_intf->hw_idx,
1122 &rsrc_data->intra_client_mask);
1123 } else {
1124 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001125 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001126 return -ENODEV;
1127 }
1128 comp_grp_local = list_first_entry(
1129 &ver2_bus_priv->free_comp_grp,
1130 struct cam_isp_resource_node, list);
1131 rsrc_data = comp_grp_local->res_priv;
1132 }
1133
1134 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001135 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001136 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1137
1138 rsrc_data->is_master = is_master;
1139 rsrc_data->composite_mask = 0;
1140 rsrc_data->unique_id = unique_id;
1141 rsrc_data->comp_grp_local_idx = out_port_info->comp_grp_id;
1142
1143 list_add_tail(&comp_grp_local->list,
1144 &ver2_bus_priv->used_comp_grp);
1145
1146 } else {
1147 rsrc_data = comp_grp_local->res_priv;
1148 /* Do not support runtime change in composite mask */
1149 if (comp_grp_local->res_state ==
1150 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001151 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001152 comp_grp_local->res_state,
1153 rsrc_data->comp_grp_type);
1154 return -EBUSY;
1155 }
1156 }
1157
Harsh Shah19f55812017-06-26 18:58:49 -07001158 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -07001159 *comp_grp = comp_grp_local;
1160
1161 return rc;
1162}
1163
1164static int cam_vfe_bus_release_comp_grp(
1165 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1166 struct cam_isp_resource_node *in_comp_grp)
1167{
1168 struct cam_isp_resource_node *comp_grp = NULL;
1169 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1170 int match_found = 0;
1171
1172 if (!in_comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001173 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_rsrc_data);
Harsh Shaha1af8822017-05-11 22:06:36 -07001174 return -EINVAL;
1175 }
1176
1177 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
1178 /* Already Released. Do Nothing */
1179 return 0;
1180 }
1181
1182 in_rsrc_data = in_comp_grp->res_priv;
1183
1184 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1185 if (comp_grp == in_comp_grp) {
1186 match_found = 1;
1187 break;
1188 }
1189 }
1190
1191 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001192 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001193 in_rsrc_data->comp_grp_type);
1194 return -ENODEV;
1195 }
1196
1197
1198 list_del(&comp_grp->list);
1199 if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1200 in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1201 list_add_tail(&comp_grp->list,
1202 &ver2_bus_priv->free_dual_comp_grp);
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001203 else if (in_rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1204 && in_rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
Harsh Shaha1af8822017-05-11 22:06:36 -07001205 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1206
Harsh Shaha1af8822017-05-11 22:06:36 -07001207 in_rsrc_data->unique_id = 0;
1208 in_rsrc_data->comp_grp_local_idx = 0;
1209 in_rsrc_data->composite_mask = 0;
1210 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1211
Harsh Shah19f55812017-06-26 18:58:49 -07001212 comp_grp->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001213 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1214
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001215 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001216}
1217
1218static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1219{
1220 int rc = 0;
1221 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1222 comp_grp->res_priv;
1223 struct cam_vfe_bus_ver2_common_data *common_data =
1224 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001225 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001226
1227 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1228 rsrc_data->hw_regs->comp_mask);
1229
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001230 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1231 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1232 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001233
1234 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1235 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1236 rsrc_data->is_master) {
1237 int dual_comp_grp = (rsrc_data->comp_grp_type -
1238 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1239 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1240 common_data->common_reg->dual_master_comp_cfg);
1241
1242 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1243 intra_client_en |=
1244 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1245
1246 cam_io_w_mb(intra_client_en, common_data->mem_base +
1247 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001248
1249 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1250 } else {
1251 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1252 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1253 (1 << (rsrc_data->comp_grp_type + 5));
1254 }
1255
1256 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001257 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001258 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1259 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1260 bus_irq_reg_mask, comp_grp,
1261 comp_grp->top_half_handler,
1262 cam_ife_mgr_do_tasklet_buf_done,
1263 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1264 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001265 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001266 rsrc_data->comp_grp_type);
1267 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001268 }
1269
1270 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001271
Harsh Shaha1af8822017-05-11 22:06:36 -07001272 return rc;
1273}
1274
1275static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1276{
1277 int rc = 0;
1278 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1279 comp_grp->res_priv;
1280 struct cam_vfe_bus_ver2_common_data *common_data =
1281 rsrc_data->common_data;
1282
1283 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001284 rc = cam_irq_controller_unsubscribe_irq(
1285 common_data->bus_irq_controller,
1286 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001287
1288 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1289 rsrc_data->hw_regs->comp_mask);
1290 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1291 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1292 rsrc_data->is_master) {
1293 int dual_comp_grp = (rsrc_data->comp_grp_type -
1294 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1295 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1296 common_data->common_reg->dual_master_comp_cfg);
1297
1298 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1299 intra_client_en &=
1300 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1301
1302 cam_io_w_mb(intra_client_en, common_data->mem_base +
1303 common_data->common_reg->dual_master_comp_cfg);
1304 }
1305
1306 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1307
1308 return rc;
1309}
1310
1311static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1312 struct cam_irq_th_payload *th_payload)
1313{
Harsh Shah19f55812017-06-26 18:58:49 -07001314 int32_t rc;
1315 int i;
1316 struct cam_isp_resource_node *comp_grp = NULL;
1317 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1318 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1319
1320 comp_grp = th_payload->handler_priv;
1321 if (!comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001322 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001323 return -ENODEV;
1324 }
1325
1326 rsrc_data = comp_grp->res_priv;
1327
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001328 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1329 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001330
1331 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1332 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001333 CAM_ERR_RATE_LIMIT(CAM_ISP,
1334 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001335 return rc;
1336 }
1337
1338 cam_isp_hw_get_timestamp(&evt_payload->ts);
1339
1340 evt_payload->ctx = rsrc_data->ctx;
1341 evt_payload->core_index = rsrc_data->common_data->core_index;
1342 evt_payload->evt_id = evt_id;
1343
1344 for (i = 0; i < th_payload->num_registers; i++)
1345 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1346
1347 th_payload->evt_payload_priv = evt_payload;
1348
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001349 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001350 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001351}
1352
1353static int cam_vfe_bus_handle_comp_done_bottom_half(
1354 void *handler_priv,
1355 void *evt_payload_priv)
1356{
1357 int rc = CAM_VFE_IRQ_STATUS_ERR;
1358 struct cam_isp_resource_node *comp_grp = handler_priv;
1359 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1360 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001361 uint32_t *cam_ife_irq_regs;
1362 uint32_t status_reg;
1363 uint32_t comp_err_reg;
1364 uint32_t comp_grp_id;
1365
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001366 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001367
Harsh Shah23557ae2017-05-13 18:14:34 -07001368 if (!evt_payload)
1369 return rc;
1370
1371 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001372
Harsh Shaha1af8822017-05-11 22:06:36 -07001373 switch (rsrc_data->comp_grp_type) {
1374 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1375 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1376 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1377 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1378 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1379 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001380 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001381 CAM_VFE_BUS_VER2_COMP_GRP_0);
1382
1383 /* Check for Regular composite error */
1384 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1385
1386 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1387 if ((status_reg & BIT(11)) &&
1388 (comp_err_reg & rsrc_data->composite_mask)) {
1389 /* Check for Regular composite error */
1390 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1391 break;
1392 }
1393
1394 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1395 /* Check for Regular composite Overwrite */
1396 if ((status_reg & BIT(12)) &&
1397 (comp_err_reg & rsrc_data->composite_mask)) {
1398 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1399 break;
1400 }
1401
Harsh Shah23557ae2017-05-13 18:14:34 -07001402 /* Regular Composite SUCCESS */
1403 if (status_reg & BIT(comp_grp_id + 5)) {
1404 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1405 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001406 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001407 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001408
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001409 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001410 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001411 break;
1412
1413 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1414 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1415 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1416 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1417 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1418 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001419 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001420 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1421
1422 /* Check for DUAL composite error */
1423 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1424
1425 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1426 if ((status_reg & BIT(6)) &&
1427 (comp_err_reg & rsrc_data->composite_mask)) {
1428 /* Check for DUAL composite error */
1429 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1430 break;
1431 }
1432
1433 /* Check for Dual composite Overwrite */
1434 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1435 if ((status_reg & BIT(7)) &&
1436 (comp_err_reg & rsrc_data->composite_mask)) {
1437 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1438 break;
1439 }
1440
Harsh Shah23557ae2017-05-13 18:14:34 -07001441 /* DUAL Composite SUCCESS */
1442 if (status_reg & BIT(comp_grp_id)) {
1443 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1444 ~BIT(comp_grp_id + 5);
Harsh Shaha1af8822017-05-11 22:06:36 -07001445 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001446 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001447
1448 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001449 default:
1450 rc = CAM_VFE_IRQ_STATUS_ERR;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001451 CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001452 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001453 break;
1454 }
1455
1456 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001457 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001458 &evt_payload);
1459
1460 return rc;
1461}
1462
1463static int cam_vfe_bus_init_comp_grp(uint32_t index,
1464 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1465 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1466 struct cam_isp_resource_node *comp_grp)
1467{
Harsh Shah545df9a2017-06-16 16:43:17 -07001468 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001469
1470 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1471 GFP_KERNEL);
1472 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001473 CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001474 return -ENOMEM;
1475 }
1476 comp_grp->res_priv = rsrc_data;
1477
1478 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1479 INIT_LIST_HEAD(&comp_grp->list);
1480
1481 rsrc_data->comp_grp_type = index;
1482 rsrc_data->common_data = &ver2_bus_priv->common_data;
1483 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1484 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1485
Harsh Shaha1af8822017-05-11 22:06:36 -07001486 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1487 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1488 list_add_tail(&comp_grp->list,
1489 &ver2_bus_priv->free_dual_comp_grp);
1490 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1491 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1492 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1493
1494 comp_grp->start = cam_vfe_bus_start_comp_grp;
1495 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1496 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1497 comp_grp->bottom_half_handler =
1498 cam_vfe_bus_handle_comp_done_bottom_half;
1499 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1500
1501 return 0;
1502}
1503
Harsh Shah545df9a2017-06-16 16:43:17 -07001504static int cam_vfe_bus_deinit_comp_grp(
1505 struct cam_isp_resource_node *comp_grp)
1506{
1507 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1508 comp_grp->res_priv;
1509
1510 comp_grp->start = NULL;
1511 comp_grp->stop = NULL;
1512 comp_grp->top_half_handler = NULL;
1513 comp_grp->bottom_half_handler = NULL;
1514 comp_grp->hw_intf = NULL;
1515
1516 list_del_init(&comp_grp->list);
1517 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1518
1519 comp_grp->res_priv = NULL;
1520
1521 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001522 CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001523 return -ENODEV;
1524 }
1525 kfree(rsrc_data);
1526
1527 return 0;
1528}
1529
Harsh Shah19f55812017-06-26 18:58:49 -07001530static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1531 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001532{
1533 int rc = -ENODEV;
1534 int i;
1535 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1536 uint32_t format;
1537 uint32_t num_wm;
1538 uint32_t subscribe_irq;
1539 uint32_t client_done_mask;
1540 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1541 struct cam_vfe_acquire_args *acq_args = acquire_args;
1542 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1543 struct cam_isp_resource_node *rsrc_node = NULL;
1544 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1545
1546 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001547 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001548 return -EINVAL;
1549 }
1550
1551 out_acquire_args = &acq_args->vfe_out;
1552 format = out_acquire_args->out_port_info->format;
1553
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001554 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001555 out_acquire_args->out_port_info->res_type);
1556
1557 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1558 out_acquire_args->out_port_info->res_type);
1559 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1560 return -ENODEV;
1561
1562 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1563 if (num_wm < 1)
1564 return -EINVAL;
1565
1566 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1567 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001568 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001569 vfe_out_res_id, rsrc_node->res_state);
1570 return -EBUSY;
1571 }
1572
1573 rsrc_data = rsrc_node->res_priv;
1574 rsrc_data->num_wm = num_wm;
1575 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1576 rsrc_node->tasklet_info = acq_args->tasklet;
1577 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1578 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1579
1580 /* Reserve Composite Group */
1581 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1582 CAM_ISP_RES_COMP_GROUP_NONE &&
1583 out_acquire_args->out_port_info->comp_grp_id <
1584 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1585 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1586 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001587 acq_args->tasklet,
1588 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001589 out_acquire_args->unique_id,
1590 out_acquire_args->is_dual,
1591 out_acquire_args->is_master,
1592 out_acquire_args->dual_slave_core,
1593 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001594 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001595 CAM_ERR(CAM_ISP,
1596 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001597 rsrc_data->common_data->core_index,
1598 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001599 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001600 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001601
1602 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001603 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001604 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001605 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001606
1607 /* Reserve WM */
1608 for (i = 0; i < num_wm; i++) {
1609 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1610 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001611 acq_args->tasklet,
1612 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001613 vfe_out_res_id,
1614 i,
1615 out_acquire_args->split_id,
1616 subscribe_irq,
1617 &rsrc_data->wm_res[i],
1618 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001619 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001620 CAM_ERR(CAM_ISP,
1621 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001622 rsrc_data->common_data->core_index,
1623 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001624 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001625 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001626
1627 if (rsrc_data->comp_grp)
1628 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1629 client_done_mask);
1630 }
1631
1632 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1633 out_acquire_args->rsrc_node = rsrc_node;
1634
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001635 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001636 return rc;
1637
1638release_wm:
1639 for (i--; i >= 0; i--)
1640 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1641
1642 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1643 rsrc_data->comp_grp);
1644
1645 return rc;
1646}
1647
Harsh Shah19f55812017-06-26 18:58:49 -07001648static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1649 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001650{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001651 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001652 struct cam_isp_resource_node *vfe_out = NULL;
1653 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1654
1655 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001656 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001657 bus_priv, release_args);
1658 return -EINVAL;
1659 }
1660
1661 vfe_out = release_args;
1662 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001663
Harsh Shaha1af8822017-05-11 22:06:36 -07001664 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001665 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001666 vfe_out->res_state);
1667 }
1668
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001669 for (i = 0; i < rsrc_data->num_wm; i++)
1670 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1671 rsrc_data->num_wm = 0;
1672
1673 if (rsrc_data->comp_grp)
1674 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1675 rsrc_data->comp_grp = NULL;
1676
1677 vfe_out->tasklet_info = NULL;
1678 vfe_out->cdm_ops = NULL;
1679 rsrc_data->cdm_util_ops = NULL;
1680
Harsh Shaha1af8822017-05-11 22:06:36 -07001681 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1682 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1683
1684 return 0;
1685}
1686
Harsh Shah19f55812017-06-26 18:58:49 -07001687static int cam_vfe_bus_start_vfe_out(
1688 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001689{
1690 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001691 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1692 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1693
1694 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001695 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001696 return -EINVAL;
1697 }
1698
1699 rsrc_data = vfe_out->res_priv;
1700 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001701
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001702 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001703
1704 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001705 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001706 vfe_out->res_state);
1707 return -EACCES;
1708 }
1709
1710 for (i = 0; i < rsrc_data->num_wm; i++)
1711 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1712
1713 if (rsrc_data->comp_grp)
1714 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1715
Harsh Shaha1af8822017-05-11 22:06:36 -07001716 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1717 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1718 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1719 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1720 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1721 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001722 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1723 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1724 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1725 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1726 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1727 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1728 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1729 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1730 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1731
Harsh Shah23557ae2017-05-13 18:14:34 -07001732 /* no clock gating at bus input */
1733 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1734
1735 /* BUS_WR_TEST_BUS_CTRL */
1736 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
1737
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05301738 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07001739 return rc;
1740}
1741
Harsh Shah19f55812017-06-26 18:58:49 -07001742static int cam_vfe_bus_stop_vfe_out(
1743 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001744{
1745 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001746 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1747
1748 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001749 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001750 return -EINVAL;
1751 }
1752
1753 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001754
1755 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
1756 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
1757 return rc;
1758 }
1759
1760 if (rsrc_data->comp_grp)
1761 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
1762
1763 for (i = 0; i < rsrc_data->num_wm; i++)
1764 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
1765
Harsh Shaha1af8822017-05-11 22:06:36 -07001766
1767 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1768 return rc;
1769}
1770
1771static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
1772 struct cam_irq_th_payload *th_payload)
1773{
1774 return -EPERM;
1775}
1776
1777static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
1778 void *handler_priv,
1779 void *evt_payload_priv)
1780{
1781 int rc = -EINVAL;
1782 struct cam_isp_resource_node *vfe_out = handler_priv;
1783 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1784
1785 /*
1786 * If this resource has Composite Group then we only handle
1787 * Composite done. We acquire Composite if number of WM > 1.
1788 * So Else case is only one individual buf_done = WM[0].
1789 */
1790 if (rsrc_data->comp_grp) {
1791 rc = rsrc_data->comp_grp->bottom_half_handler(
1792 rsrc_data->comp_grp, evt_payload_priv);
1793 } else {
1794 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07001795 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07001796 }
1797
1798 return rc;
1799}
1800
1801static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
1802 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1803 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1804 struct cam_isp_resource_node *vfe_out)
1805{
1806 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1807 int rc = 0;
1808
1809 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
1810 GFP_KERNEL);
1811 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001812 CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001813 rc = -ENOMEM;
1814 return rc;
1815 }
1816 vfe_out->res_priv = rsrc_data;
1817
1818 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
1819 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1820 INIT_LIST_HEAD(&vfe_out->list);
1821
1822 rsrc_data->out_type = index;
1823 rsrc_data->common_data = &ver2_bus_priv->common_data;
1824 rsrc_data->max_width =
1825 ver2_hw_info->vfe_out_hw_info[index].max_width;
1826 rsrc_data->max_height =
1827 ver2_hw_info->vfe_out_hw_info[index].max_height;
1828
1829 vfe_out->start = cam_vfe_bus_start_vfe_out;
1830 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
1831 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
1832 vfe_out->bottom_half_handler =
1833 cam_vfe_bus_handle_vfe_out_done_bottom_half;
1834 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
1835
1836 return 0;
1837}
1838
Harsh Shah545df9a2017-06-16 16:43:17 -07001839static int cam_vfe_bus_deinit_vfe_out_resource(
1840 struct cam_isp_resource_node *vfe_out)
1841{
1842 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1843
1844 vfe_out->start = NULL;
1845 vfe_out->stop = NULL;
1846 vfe_out->top_half_handler = NULL;
1847 vfe_out->bottom_half_handler = NULL;
1848 vfe_out->hw_intf = NULL;
1849
1850 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1851 INIT_LIST_HEAD(&vfe_out->list);
1852 vfe_out->res_priv = NULL;
1853
1854 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001855 CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001856 return -ENOMEM;
1857 }
1858 kfree(rsrc_data);
1859
1860 return 0;
1861}
1862
Harsh Shaha1af8822017-05-11 22:06:36 -07001863static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
1864 struct cam_irq_th_payload *th_payload)
1865{
Harsh Shaha1af8822017-05-11 22:06:36 -07001866 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001867
Harsh Shah19f55812017-06-26 18:58:49 -07001868 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001869 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07001870 return cam_irq_controller_handle_irq(evt_id,
1871 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07001872}
1873
1874static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
1875 uint32_t arg_size)
1876{
1877 struct cam_vfe_bus_ver2_priv *bus_priv;
1878 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001879 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07001880 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
1881 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001882 uint32_t *reg_val_pair;
1883 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07001884 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001885
1886 /*
1887 * Need the entire buf io config so we can get the stride info
1888 * for the wm.
1889 */
1890
1891 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
1892 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
1893
1894 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
1895 update_buf->cdm.res->res_priv;
1896
1897 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001898 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07001899 return -EINVAL;
1900 }
1901
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001902 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001903 CAM_ERR(CAM_ISP,
1904 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001905 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07001906 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001907 }
1908
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001909 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
1910 io_cfg = update_buf->io_cfg;
1911
1912 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07001913 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001914 CAM_ERR(CAM_ISP,
1915 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07001916 j, MAX_REG_VAL_PAIR_SIZE);
1917 return -ENOMEM;
1918 }
1919
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001920 wm_data = vfe_out_data->wm_res[i]->res_priv;
1921
1922 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301923 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
1924 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001925 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1926 wm_data->hw_regs->stride,
1927 io_cfg->planes[i].plane_stride);
1928 wm_data->stride = io_cfg->planes[i].plane_stride;
1929 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001930 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001931
1932 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
1933 !wm_data->init_cfg_done) {
1934 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1935 wm_data->hw_regs->framedrop_pattern,
1936 io_cfg->framedrop_pattern);
1937 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
1938 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001939 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
1940 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001941
1942 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
1943 !wm_data->init_cfg_done) {
1944 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1945 wm_data->hw_regs->framedrop_period,
1946 io_cfg->framedrop_period);
1947 wm_data->framedrop_period = io_cfg->framedrop_period;
1948 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001949 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
1950 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001951
1952 if (wm_data->irq_subsample_period != io_cfg->subsample_period
1953 || !wm_data->init_cfg_done) {
1954 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1955 wm_data->hw_regs->irq_subsample_period,
1956 io_cfg->subsample_period);
1957 wm_data->irq_subsample_period =
1958 io_cfg->subsample_period;
1959 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001960 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001961 wm_data->irq_subsample_period);
1962
1963 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
1964 || !wm_data->init_cfg_done) {
1965 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1966 wm_data->hw_regs->irq_subsample_pattern,
1967 io_cfg->subsample_pattern);
1968 wm_data->irq_subsample_pattern =
1969 io_cfg->subsample_pattern;
1970 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001971 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001972 wm_data->irq_subsample_pattern);
1973
1974 if (wm_data->en_ubwc) {
1975 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001976 CAM_ERR(CAM_ISP,
1977 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001978 return -EINVAL;
1979 }
1980 if (wm_data->packer_cfg !=
1981 io_cfg->planes[i].packer_config ||
1982 !wm_data->init_cfg_done) {
1983 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1984 wm_data->hw_regs->packer_cfg,
1985 io_cfg->planes[i].packer_config);
1986 wm_data->packer_cfg =
1987 io_cfg->planes[i].packer_config;
1988 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001989 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
1990 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001991
1992 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
1993 || !wm_data->init_cfg_done) {
1994 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
1995 wm_data->hw_regs->ubwc_regs->tile_cfg,
1996 io_cfg->planes[i].tile_config);
1997 wm_data->tile_cfg =
1998 io_cfg->planes[i].tile_config;
1999 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002000 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002001
2002 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2003 !wm_data->init_cfg_done) {
2004 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2005 wm_data->hw_regs->ubwc_regs->h_init,
2006 io_cfg->planes[i].h_init);
2007 wm_data->h_init = io_cfg->planes[i].h_init;
2008 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002009 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002010
2011 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2012 !wm_data->init_cfg_done) {
2013 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2014 wm_data->hw_regs->ubwc_regs->v_init,
2015 io_cfg->planes[i].v_init);
2016 wm_data->v_init = io_cfg->planes[i].v_init;
2017 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002018 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002019
2020 if (wm_data->ubwc_meta_stride !=
2021 io_cfg->planes[i].meta_stride ||
2022 !wm_data->init_cfg_done) {
2023 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2024 wm_data->hw_regs->ubwc_regs->
2025 meta_stride,
2026 io_cfg->planes[i].meta_stride);
2027 wm_data->ubwc_meta_stride =
2028 io_cfg->planes[i].meta_stride;
2029 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002030 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2031 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002032
2033 if (wm_data->ubwc_mode_cfg !=
2034 io_cfg->planes[i].mode_config ||
2035 !wm_data->init_cfg_done) {
2036 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2037 wm_data->hw_regs->ubwc_regs->mode_cfg,
2038 io_cfg->planes[i].mode_config);
2039 wm_data->ubwc_mode_cfg =
2040 io_cfg->planes[i].mode_config;
2041 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002042 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2043 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002044
2045 if (wm_data->ubwc_meta_offset !=
2046 io_cfg->planes[i].meta_offset ||
2047 !wm_data->init_cfg_done) {
2048 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2049 wm_data->hw_regs->ubwc_regs->
2050 meta_offset,
2051 io_cfg->planes[i].meta_offset);
2052 wm_data->ubwc_meta_offset =
2053 io_cfg->planes[i].meta_offset;
2054 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002055 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002056 wm_data->ubwc_meta_offset);
2057
2058 /* UBWC meta address */
2059 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2060 wm_data->hw_regs->ubwc_regs->meta_addr,
2061 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002062 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002063 update_buf->image_buf[i]);
2064 }
2065
2066 /* WM Image address */
2067 if (wm_data->en_ubwc)
2068 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2069 wm_data->hw_regs->image_addr,
2070 (update_buf->image_buf[i] +
2071 io_cfg->planes[i].meta_size));
2072 else
2073 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2074 wm_data->hw_regs->image_addr,
2075 update_buf->image_buf[i]);
2076
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002077 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002078
Junzhe Zou193d78c2017-05-16 15:10:54 -07002079 frame_inc = io_cfg->planes[i].plane_stride *
2080 io_cfg->planes[i].slice_height;
2081 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2082 wm_data->hw_regs->frame_inc, frame_inc);
2083
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002084 /* enable the WM */
2085 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2086 wm_data->hw_regs->cfg,
2087 wm_data->en_cfg);
2088
2089 /* set initial configuration done */
2090 if (!wm_data->init_cfg_done)
2091 wm_data->init_cfg_done = 1;
2092 }
2093
2094 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002095
2096 /* cdm util returns dwords, need to convert to bytes */
2097 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002098 CAM_ERR(CAM_ISP,
2099 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002100 update_buf->cdm.size, size);
2101 return -ENOMEM;
2102 }
2103
Harsh Shaha1af8822017-05-11 22:06:36 -07002104 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002105 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2106
Harsh Shaha1af8822017-05-11 22:06:36 -07002107 /* cdm util returns dwords, need to convert to bytes */
2108 update_buf->cdm.used_bytes = size * 4;
2109
2110 return 0;
2111}
2112
Harsh Shah19f55812017-06-26 18:58:49 -07002113static int cam_vfe_bus_start_hw(void *hw_priv,
2114 void *start_hw_args, uint32_t arg_size)
2115{
2116 return cam_vfe_bus_start_vfe_out(hw_priv);
2117}
2118
2119static int cam_vfe_bus_stop_hw(void *hw_priv,
2120 void *stop_hw_args, uint32_t arg_size)
2121{
2122 return cam_vfe_bus_stop_vfe_out(hw_priv);
2123}
2124
2125static int cam_vfe_bus_init_hw(void *hw_priv,
2126 void *init_hw_args, uint32_t arg_size)
2127{
2128 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2129 uint32_t top_irq_reg_mask[2] = {0};
2130
2131 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002132 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002133 return -EINVAL;
2134 }
2135
2136 top_irq_reg_mask[0] = (1 << 9);
2137
2138 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2139 bus_priv->common_data.vfe_irq_controller,
2140 CAM_IRQ_PRIORITY_2,
2141 top_irq_reg_mask,
2142 bus_priv,
2143 cam_vfe_bus_ver2_handle_irq,
2144 NULL,
2145 NULL,
2146 NULL);
2147
2148 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002149 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002150 return -EFAULT;
2151 }
2152
2153 return 0;
2154}
2155
2156static int cam_vfe_bus_deinit_hw(void *hw_priv,
2157 void *deinit_hw_args, uint32_t arg_size)
2158{
2159 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2160 int rc;
2161
2162 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002163 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002164 return -EINVAL;
2165 }
2166
2167 rc = cam_irq_controller_unsubscribe_irq(
2168 bus_priv->common_data.vfe_irq_controller,
2169 bus_priv->irq_handle);
2170 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002171 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002172
2173 return rc;
2174}
2175
Harsh Shaha1af8822017-05-11 22:06:36 -07002176static int cam_vfe_bus_process_cmd(void *priv,
2177 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2178{
2179 int rc = -EINVAL;
2180
2181 if (!priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002182 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
Harsh Shaha1af8822017-05-11 22:06:36 -07002183 return -EINVAL;
2184 }
2185
2186 switch (cmd_type) {
2187 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2188 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2189 break;
2190 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002191 CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
Harsh Shaha1af8822017-05-11 22:06:36 -07002192 cmd_type);
2193 break;
2194 }
2195
2196 return rc;
2197}
2198
2199int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002200 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002201 struct cam_hw_intf *hw_intf,
2202 void *bus_hw_info,
2203 void *vfe_irq_controller,
2204 struct cam_vfe_bus **vfe_bus)
2205{
2206 int i, rc = 0;
2207 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2208 struct cam_vfe_bus *vfe_bus_local;
2209 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2210
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002211 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002212
Harsh Shah19f55812017-06-26 18:58:49 -07002213 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002214 CAM_ERR(CAM_ISP,
2215 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2216 soc_info, hw_intf, bus_hw_info);
2217 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002218 rc = -EINVAL;
2219 goto end;
2220 }
2221
Harsh Shaha1af8822017-05-11 22:06:36 -07002222 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2223 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002224 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002225 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002226 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002227 }
2228
2229 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2230 GFP_KERNEL);
2231 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002232 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002233 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002234 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002235 }
2236 vfe_bus_local->bus_priv = bus_priv;
2237
Harsh Shah19f55812017-06-26 18:58:49 -07002238 bus_priv->common_data.core_index = soc_info->index;
2239 bus_priv->common_data.mem_base =
2240 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002241 bus_priv->common_data.hw_intf = hw_intf;
2242 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2243 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
2244
Harsh Shah19f55812017-06-26 18:58:49 -07002245 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2246 &ver2_hw_info->common_reg.irq_reg_info,
2247 &bus_priv->common_data.bus_irq_controller);
2248 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002249 CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002250 goto free_bus_priv;
2251 }
2252
Harsh Shaha1af8822017-05-11 22:06:36 -07002253 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2254 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2255 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2256
2257 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2258 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2259 &bus_priv->bus_client[i]);
2260 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002261 CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002262 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002263 }
2264 }
2265
2266 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2267 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2268 &bus_priv->comp_grp[i]);
2269 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002270 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002271 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002272 }
2273 }
2274
2275 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2276 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2277 &bus_priv->vfe_out[i]);
2278 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002279 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002280 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002281 }
2282 }
2283
Harsh Shah19f55812017-06-26 18:58:49 -07002284 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2285 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2286 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2287 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2288 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002289 }
2290
Harsh Shah19f55812017-06-26 18:58:49 -07002291 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2292 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2293 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2294 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2295 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2296 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2297 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002298 vfe_bus_local->bottom_half_handler = NULL;
Harsh Shah19f55812017-06-26 18:58:49 -07002299 vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002300
2301 *vfe_bus = vfe_bus_local;
2302
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002303 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002304 return rc;
2305
Harsh Shah545df9a2017-06-16 16:43:17 -07002306deinit_vfe_out:
2307 if (i < 0)
2308 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2309 for (--i; i >= 0; i--)
2310 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2311
2312deinit_comp_grp:
2313 if (i < 0)
2314 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2315 for (--i; i >= 0; i--)
2316 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2317
2318deinit_wm:
2319 if (i < 0)
2320 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2321 for (--i; i >= 0; i--)
2322 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2323
Harsh Shah19f55812017-06-26 18:58:49 -07002324free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002325 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002326
2327free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002328 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002329
2330end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002331 return rc;
2332}
Harsh Shah545df9a2017-06-16 16:43:17 -07002333
2334int cam_vfe_bus_ver2_deinit(
2335 struct cam_vfe_bus **vfe_bus)
2336{
2337 int i, rc = 0;
2338 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2339 struct cam_vfe_bus *vfe_bus_local;
2340
2341 if (!vfe_bus || !*vfe_bus) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002342 CAM_ERR(CAM_ISP, "Error! Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002343 return -EINVAL;
2344 }
2345 vfe_bus_local = *vfe_bus;
2346
2347 bus_priv = vfe_bus_local->bus_priv;
2348 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002349 CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002350 rc = -ENODEV;
2351 goto free_bus_local;
2352 }
2353
Harsh Shah19f55812017-06-26 18:58:49 -07002354 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2355 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2356 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002357
2358 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2359 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2360 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002361 CAM_ERR(CAM_ISP,
2362 "Error! Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002363 }
2364
2365 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2366 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2367 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002368 CAM_ERR(CAM_ISP,
2369 "Error! Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002370 }
2371
2372 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2373 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2374 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002375 CAM_ERR(CAM_ISP,
2376 "Error! Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002377 }
2378
2379 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2380 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2381 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2382
Harsh Shah19f55812017-06-26 18:58:49 -07002383 rc = cam_irq_controller_deinit(
2384 &bus_priv->common_data.bus_irq_controller);
2385 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002386 CAM_ERR(CAM_ISP,
2387 "Error! Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002388
Harsh Shah545df9a2017-06-16 16:43:17 -07002389 kfree(vfe_bus_local->bus_priv);
2390
2391free_bus_local:
2392 kfree(vfe_bus_local);
2393
2394 *vfe_bus = NULL;
2395
2396 return rc;
2397}
2398