blob: af0331284a2b2849748f83d8e85c215cc926d8db [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"
Harsh Shahf7136392017-08-29 12:42:52 -070016#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070017#include "cam_cdm_util.h"
18#include "cam_hw_intf.h"
Harsh Shah19f55812017-06-26 18:58:49 -070019#include "cam_ife_hw_mgr.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070020#include "cam_vfe_hw_intf.h"
21#include "cam_irq_controller.h"
Harsh Shah19f55812017-06-26 18:58:49 -070022#include "cam_tasklet_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070023#include "cam_vfe_bus.h"
24#include "cam_vfe_bus_ver2.h"
25#include "cam_vfe_core.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070026#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070027
Harsh Shah19f55812017-06-26 18:58:49 -070028static const char drv_name[] = "vfe_bus";
29
30#define CAM_VFE_BUS_IRQ_REG0 0
31#define CAM_VFE_BUS_IRQ_REG1 1
32#define CAM_VFE_BUS_IRQ_REG2 2
33#define CAM_VFE_BUS_IRQ_MAX 3
34
35#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
Harsh Shah23557ae2017-05-13 18:14:34 -070036
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +053037#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
38#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
39
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -070040#define ALIGNUP(value, alignment) \
41 ((value + alignment - 1) / alignment * alignment)
42
Junzhe Zou193d78c2017-05-16 15:10:54 -070043#define MAX_BUF_UPDATE_REG_NUM \
44 (sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070045#define MAX_REG_VAL_PAIR_SIZE \
Harsh Shah19f55812017-06-26 18:58:49 -070046 (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070047
48#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
Harsh Shah19f55812017-06-26 18:58:49 -070049 do { \
50 buf_array[index++] = offset; \
51 buf_array[index++] = val; \
52 } while (0)
Harsh Shaha1af8822017-05-11 22:06:36 -070053
54enum cam_vfe_bus_packer_format {
55 PACKER_FMT_PLAIN_128 = 0x0,
56 PACKER_FMT_PLAIN_8 = 0x1,
57 PACKER_FMT_PLAIN_16_10BPP = 0x2,
58 PACKER_FMT_PLAIN_16_12BPP = 0x3,
59 PACKER_FMT_PLAIN_16_14BPP = 0x4,
60 PACKER_FMT_PLAIN_16_16BPP = 0x5,
61 PACKER_FMT_ARGB_10 = 0x6,
62 PACKER_FMT_ARGB_12 = 0x7,
63 PACKER_FMT_ARGB_14 = 0x8,
64 PACKER_FMT_PLAIN_32_20BPP = 0x9,
65 PACKER_FMT_PLAIN_64 = 0xA,
66 PACKER_FMT_TP_10 = 0xB,
67 PACKER_FMT_PLAIN_32_32BPP = 0xC,
68 PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
69 PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
70 PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
71 PACKER_FMT_MAX = 0xF,
72};
73
Karthik Anantha Ram01974172017-09-01 10:42:22 -070074enum cam_vfe_bus_comp_grp_id {
75 CAM_VFE_BUS_COMP_GROUP_NONE = -EINVAL,
76 CAM_VFE_BUS_COMP_GROUP_ID_0 = 0x0,
77 CAM_VFE_BUS_COMP_GROUP_ID_1 = 0x1,
78 CAM_VFE_BUS_COMP_GROUP_ID_2 = 0x2,
79 CAM_VFE_BUS_COMP_GROUP_ID_3 = 0x3,
80 CAM_VFE_BUS_COMP_GROUP_ID_4 = 0x4,
81 CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5,
82};
83
Harsh Shaha1af8822017-05-11 22:06:36 -070084struct cam_vfe_bus_ver2_common_data {
Harsh Shah19f55812017-06-26 18:58:49 -070085 uint32_t core_index;
Harsh Shaha1af8822017-05-11 22:06:36 -070086 void __iomem *mem_base;
87 struct cam_hw_intf *hw_intf;
88 void *bus_irq_controller;
89 void *vfe_irq_controller;
90 struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070091 uint32_t io_buf_update[
Harsh Shah19f55812017-06-26 18:58:49 -070092 MAX_REG_VAL_PAIR_SIZE];
93
94 struct cam_vfe_bus_irq_evt_payload evt_payload[
95 CAM_VFE_BUS_VER2_PAYLOAD_MAX];
96 struct list_head free_payload_list;
Harsh Shaha1af8822017-05-11 22:06:36 -070097};
98
99struct cam_vfe_bus_ver2_wm_resource_data {
100 uint32_t index;
101 struct cam_vfe_bus_ver2_common_data *common_data;
102 struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
Harsh Shah19f55812017-06-26 18:58:49 -0700103 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700104
105 uint32_t irq_enabled;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700106 bool init_cfg_done;
107 bool hfr_cfg_done;
Harsh Shah19f55812017-06-26 18:58:49 -0700108
Harsh Shaha1af8822017-05-11 22:06:36 -0700109 uint32_t offset;
110 uint32_t width;
111 uint32_t height;
112 uint32_t stride;
113 uint32_t format;
114 enum cam_vfe_bus_packer_format pack_fmt;
115
116 uint32_t burst_len;
Harsh Shaha1af8822017-05-11 22:06:36 -0700117
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700118 uint32_t en_ubwc;
119 uint32_t packer_cfg;
120 uint32_t tile_cfg;
121 uint32_t h_init;
122 uint32_t v_init;
123 uint32_t ubwc_meta_stride;
124 uint32_t ubwc_mode_cfg;
125 uint32_t ubwc_meta_offset;
126
Harsh Shaha1af8822017-05-11 22:06:36 -0700127 uint32_t irq_subsample_period;
128 uint32_t irq_subsample_pattern;
129 uint32_t framedrop_period;
130 uint32_t framedrop_pattern;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700131
132 uint32_t en_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -0700133};
134
135struct cam_vfe_bus_ver2_comp_grp_data {
136 enum cam_vfe_bus_ver2_comp_grp_type comp_grp_type;
137 struct cam_vfe_bus_ver2_common_data *common_data;
138 struct cam_vfe_bus_ver2_reg_offset_comp_grp *hw_regs;
139
140 uint32_t irq_enabled;
141 uint32_t comp_grp_local_idx;
142 uint32_t unique_id;
143
144 uint32_t is_master;
145 uint32_t dual_slave_core;
146 uint32_t intra_client_mask;
147 uint32_t composite_mask;
Harsh Shah19f55812017-06-26 18:58:49 -0700148
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700149 uint32_t acquire_dev_cnt;
150 uint32_t irq_trigger_cnt;
151
Harsh Shah19f55812017-06-26 18:58:49 -0700152 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700153};
154
155struct cam_vfe_bus_ver2_vfe_out_data {
156 uint32_t out_type;
157 struct cam_vfe_bus_ver2_common_data *common_data;
158
159 uint32_t num_wm;
160 struct cam_isp_resource_node *wm_res[PLANE_MAX];
161
162 struct cam_isp_resource_node *comp_grp;
163 enum cam_isp_hw_sync_mode dual_comp_sync_mode;
164 uint32_t dual_hw_alternate_vfe_id;
165 struct list_head vfe_out_list;
166
167 uint32_t format;
168 uint32_t max_width;
169 uint32_t max_height;
170 struct cam_cdm_utils_ops *cdm_util_ops;
171};
172
Harsh Shaha1af8822017-05-11 22:06:36 -0700173struct cam_vfe_bus_ver2_priv {
174 struct cam_vfe_bus_ver2_common_data common_data;
175
176 struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
177 struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
178 struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
179
180 struct list_head free_comp_grp;
181 struct list_head free_dual_comp_grp;
182 struct list_head used_comp_grp;
183
Harsh Shah19f55812017-06-26 18:58:49 -0700184 uint32_t irq_handle;
Harsh Shaha1af8822017-05-11 22:06:36 -0700185};
186
Harsh Shah19f55812017-06-26 18:58:49 -0700187static int cam_vfe_bus_get_evt_payload(
188 struct cam_vfe_bus_ver2_common_data *common_data,
189 struct cam_vfe_bus_irq_evt_payload **evt_payload)
190{
191 if (list_empty(&common_data->free_payload_list)) {
192 *evt_payload = NULL;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700193 CAM_ERR(CAM_ISP, "No free payload");
Harsh Shah19f55812017-06-26 18:58:49 -0700194 return -ENODEV;
195 }
196
197 *evt_payload = list_first_entry(&common_data->free_payload_list,
198 struct cam_vfe_bus_irq_evt_payload, list);
199 list_del_init(&(*evt_payload)->list);
200 return 0;
201}
202
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700203static enum cam_vfe_bus_comp_grp_id
204 cam_vfe_bus_comp_grp_id_convert(uint32_t comp_grp)
205{
206 switch (comp_grp) {
207 case CAM_ISP_RES_COMP_GROUP_ID_0:
208 return CAM_VFE_BUS_COMP_GROUP_ID_0;
209 case CAM_ISP_RES_COMP_GROUP_ID_1:
210 return CAM_VFE_BUS_COMP_GROUP_ID_1;
211 case CAM_ISP_RES_COMP_GROUP_ID_2:
212 return CAM_VFE_BUS_COMP_GROUP_ID_2;
213 case CAM_ISP_RES_COMP_GROUP_ID_3:
214 return CAM_VFE_BUS_COMP_GROUP_ID_3;
215 case CAM_ISP_RES_COMP_GROUP_ID_4:
216 return CAM_VFE_BUS_COMP_GROUP_ID_4;
217 case CAM_ISP_RES_COMP_GROUP_ID_5:
218 return CAM_VFE_BUS_COMP_GROUP_ID_5;
219 case CAM_ISP_RES_COMP_GROUP_NONE:
220 default:
221 return CAM_VFE_BUS_COMP_GROUP_NONE;
222 }
223}
224
Harsh Shaha1af8822017-05-11 22:06:36 -0700225static int cam_vfe_bus_put_evt_payload(void *core_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700226 struct cam_vfe_bus_irq_evt_payload **evt_payload)
227{
228 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
229 uint32_t *ife_irq_regs = NULL;
230 uint32_t status_reg0, status_reg1, status_reg2;
231
232 if (!core_info) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700233 CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
Harsh Shah19f55812017-06-26 18:58:49 -0700234 return -EINVAL;
235 }
236 if (*evt_payload == NULL) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700237 CAM_ERR(CAM_ISP, "No payload to put");
Harsh Shah19f55812017-06-26 18:58:49 -0700238 return -EINVAL;
239 }
240
241 ife_irq_regs = (*evt_payload)->irq_reg_val;
242 status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
243 status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
244 status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
245
246 if (status_reg0 || status_reg1 || status_reg2) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700247 CAM_DBG(CAM_ISP, "status0 0x%x status1 0x%x status2 0x%x",
Harsh Shah19f55812017-06-26 18:58:49 -0700248 status_reg0, status_reg1, status_reg2);
249 return 0;
250 }
251
252 common_data = core_info;
253 list_add_tail(&(*evt_payload)->list,
254 &common_data->free_payload_list);
255 *evt_payload = NULL;
256
257 return 0;
258}
Harsh Shaha1af8822017-05-11 22:06:36 -0700259
260static int cam_vfe_bus_ver2_get_intra_client_mask(
261 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
262 enum cam_vfe_bus_ver2_vfe_core_id current_core,
263 uint32_t *intra_client_mask)
264{
265 int rc = 0;
266
267 *intra_client_mask = 0;
268
269 if (dual_slave_core == current_core) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700270 CAM_ERR(CAM_ISP,
271 "Invalid params. Same core as Master and Slave");
Harsh Shaha1af8822017-05-11 22:06:36 -0700272 return -EINVAL;
273 }
274
275 switch (current_core) {
276 case CAM_VFE_BUS_VER2_VFE_CORE_0:
277 switch (dual_slave_core) {
278 case CAM_VFE_BUS_VER2_VFE_CORE_1:
279 *intra_client_mask = 0x1;
280 break;
281 case CAM_VFE_BUS_VER2_VFE_CORE_2:
282 *intra_client_mask = 0x2;
283 break;
284 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700285 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700286 dual_slave_core);
287 rc = -EINVAL;
288 break;
289 }
290 break;
291 case CAM_VFE_BUS_VER2_VFE_CORE_1:
292 switch (dual_slave_core) {
293 case CAM_VFE_BUS_VER2_VFE_CORE_0:
294 *intra_client_mask = 0x1;
295 break;
296 case CAM_VFE_BUS_VER2_VFE_CORE_2:
297 *intra_client_mask = 0x2;
298 break;
299 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700300 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700301 dual_slave_core);
302 rc = -EINVAL;
303 break;
304 }
305 break;
306 case CAM_VFE_BUS_VER2_VFE_CORE_2:
307 switch (dual_slave_core) {
308 case CAM_VFE_BUS_VER2_VFE_CORE_0:
309 *intra_client_mask = 0x1;
310 break;
311 case CAM_VFE_BUS_VER2_VFE_CORE_1:
312 *intra_client_mask = 0x2;
313 break;
314 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700315 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700316 dual_slave_core);
317 rc = -EINVAL;
318 break;
319 }
320 break;
321 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700322 CAM_ERR(CAM_ISP,
323 "Invalid value for master core %u", current_core);
Harsh Shaha1af8822017-05-11 22:06:36 -0700324 rc = -EINVAL;
325 break;
326 }
327
328 return rc;
329}
330
331static enum cam_vfe_bus_ver2_vfe_out_type
332 cam_vfe_bus_get_out_res_id(uint32_t res_type)
333{
334 switch (res_type) {
335 case CAM_ISP_IFE_OUT_RES_FULL:
336 return CAM_VFE_BUS_VER2_VFE_OUT_FULL;
337 case CAM_ISP_IFE_OUT_RES_DS4:
338 return CAM_VFE_BUS_VER2_VFE_OUT_DS4;
339 case CAM_ISP_IFE_OUT_RES_DS16:
340 return CAM_VFE_BUS_VER2_VFE_OUT_DS16;
341 case CAM_ISP_IFE_OUT_RES_FD:
342 return CAM_VFE_BUS_VER2_VFE_OUT_FD;
343 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
344 return CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP;
345 case CAM_ISP_IFE_OUT_RES_PDAF:
346 return CAM_VFE_BUS_VER2_VFE_OUT_PDAF;
347 case CAM_ISP_IFE_OUT_RES_RDI_0:
348 return CAM_VFE_BUS_VER2_VFE_OUT_RDI0;
349 case CAM_ISP_IFE_OUT_RES_RDI_1:
350 return CAM_VFE_BUS_VER2_VFE_OUT_RDI1;
351 case CAM_ISP_IFE_OUT_RES_RDI_2:
352 return CAM_VFE_BUS_VER2_VFE_OUT_RDI2;
353 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
354 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE;
355 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
356 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST;
357 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
358 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG;
359 case CAM_ISP_IFE_OUT_RES_STATS_BF:
360 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF;
361 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
362 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG;
363 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
364 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST;
365 case CAM_ISP_IFE_OUT_RES_STATS_RS:
366 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS;
367 case CAM_ISP_IFE_OUT_RES_STATS_CS:
368 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS;
369 case CAM_ISP_IFE_OUT_RES_STATS_IHIST:
370 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST;
371 default:
372 return CAM_VFE_BUS_VER2_VFE_OUT_MAX;
373 }
374}
375
376static int cam_vfe_bus_get_num_wm(
377 enum cam_vfe_bus_ver2_vfe_out_type res_type,
378 uint32_t format)
379{
380 switch (res_type) {
381 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
382 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
383 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
384 switch (format) {
385 case CAM_FORMAT_MIPI_RAW_8:
386 case CAM_FORMAT_MIPI_RAW_10:
387 case CAM_FORMAT_MIPI_RAW_12:
388 case CAM_FORMAT_MIPI_RAW_14:
389 case CAM_FORMAT_MIPI_RAW_16:
390 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530391 case CAM_FORMAT_DPCM_10_6_10:
392 case CAM_FORMAT_DPCM_10_8_10:
393 case CAM_FORMAT_DPCM_12_6_12:
394 case CAM_FORMAT_DPCM_12_8_12:
395 case CAM_FORMAT_DPCM_14_8_14:
396 case CAM_FORMAT_DPCM_14_10_14:
397 case CAM_FORMAT_PLAIN8:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530398 case CAM_FORMAT_PLAIN16_10:
399 case CAM_FORMAT_PLAIN16_12:
400 case CAM_FORMAT_PLAIN16_14:
401 case CAM_FORMAT_PLAIN16_16:
402 case CAM_FORMAT_PLAIN32_20:
Harsh Shaha1af8822017-05-11 22:06:36 -0700403 case CAM_FORMAT_PLAIN128:
404 return 1;
405 default:
406 break;
407 }
408 break;
409 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
410 switch (format) {
411 case CAM_FORMAT_NV21:
412 case CAM_FORMAT_NV12:
413 case CAM_FORMAT_MIPI_RAW_8:
414 case CAM_FORMAT_PLAIN8:
415 case CAM_FORMAT_TP10:
416 case CAM_FORMAT_UBWC_NV12:
417 case CAM_FORMAT_UBWC_NV12_4R:
418 case CAM_FORMAT_UBWC_TP10:
419 case CAM_FORMAT_UBWC_P010:
420 return 2;
421 default:
422 break;
423 }
424 break;
425 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
426 switch (format) {
427 case CAM_FORMAT_NV21:
428 case CAM_FORMAT_NV12:
429 case CAM_FORMAT_PLAIN8:
430 case CAM_FORMAT_TP10:
431 case CAM_FORMAT_PLAIN16_10:
432 return 2;
433 default:
434 break;
435 }
436 break;
437 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
438 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
439 switch (format) {
440 case CAM_FORMAT_PD8:
441 case CAM_FORMAT_PD10:
442 return 1;
443 default:
444 break;
445 }
446 break;
447 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
448 switch (format) {
449 case CAM_FORMAT_ARGB_14:
450 case CAM_FORMAT_PLAIN8:
451 case CAM_FORMAT_PLAIN16_10:
452 case CAM_FORMAT_PLAIN16_12:
453 case CAM_FORMAT_PLAIN16_14:
454 return 1;
455 default:
456 break;
457 }
458 break;
459 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
460 switch (format) {
461 case CAM_FORMAT_PLAIN8:
462 case CAM_FORMAT_PLAIN16_10:
463 case CAM_FORMAT_PLAIN16_12:
464 case CAM_FORMAT_PLAIN16_14:
465 return 1;
466 default:
467 break;
468 }
469 break;
470 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
471 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
472 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
473 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
474 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
475 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
476 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
477 switch (format) {
478 case CAM_FORMAT_PLAIN64:
479 return 1;
480 default:
481 break;
482 }
483 break;
484 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
485 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
486 switch (format) {
487 case CAM_FORMAT_PLAIN16_16:
488 return 1;
489 default:
490 break;
491 }
492 break;
493 default:
494 break;
495 }
496
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700497 CAM_ERR(CAM_ISP, "Unsupported format %u for resource_type %u",
498 format, res_type);
Harsh Shaha1af8822017-05-11 22:06:36 -0700499
500 return -EINVAL;
501}
502
503static int cam_vfe_bus_get_wm_idx(
504 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
505 enum cam_vfe_bus_plane_type plane)
506{
507 int wm_idx = -1;
508
509 switch (vfe_out_res_id) {
510 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
511 switch (plane) {
512 case PLANE_Y:
513 wm_idx = 3;
514 break;
515 case PLANE_C:
516 wm_idx = 4;
517 break;
518 default:
519 break;
520 }
521 break;
522 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
523 switch (plane) {
524 case PLANE_Y:
525 wm_idx = 5;
526 break;
527 default:
528 break;
529 }
530 break;
531 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
532 switch (plane) {
533 case PLANE_Y:
534 wm_idx = 6;
535 break;
536 default:
537 break;
538 }
539 break;
540 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
541 switch (plane) {
542 case PLANE_Y:
543 wm_idx = 7;
544 break;
545 case PLANE_C:
546 wm_idx = 8;
547 break;
548 default:
549 break;
550 }
551 break;
552 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
553 switch (plane) {
554 case PLANE_Y:
555 wm_idx = 9;
556 break;
557 default:
558 break;
559 }
560 break;
561 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
562 switch (plane) {
563 case PLANE_Y:
564 wm_idx = 10;
565 break;
566 default:
567 break;
568 }
569 break;
570 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
571 switch (plane) {
572 case PLANE_Y:
573 wm_idx = 0;
574 break;
575 default:
576 break;
577 }
578 break;
579 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
580 switch (plane) {
581 case PLANE_Y:
582 wm_idx = 1;
583 break;
584 default:
585 break;
586 }
587 break;
588 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
589 switch (plane) {
590 case PLANE_Y:
591 wm_idx = 2;
592 break;
593 default:
594 break;
595 }
596 break;
597 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
598 switch (plane) {
599 case PLANE_Y:
600 wm_idx = 11;
601 break;
602 default:
603 break;
604 }
605 break;
606 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
607 switch (plane) {
608 case PLANE_Y:
609 wm_idx = 12;
610 break;
611 default:
612 break;
613 }
614 break;
615 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
616 switch (plane) {
617 case PLANE_Y:
618 wm_idx = 13;
619 break;
620 default:
621 break;
622 }
623 break;
624 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
625 switch (plane) {
626 case PLANE_Y:
627 wm_idx = 14;
628 break;
629 default:
630 break;
631 }
632 break;
633 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
634 switch (plane) {
635 case PLANE_Y:
636 wm_idx = 15;
637 break;
638 default:
639 break;
640 }
641 break;
642 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
643 switch (plane) {
644 case PLANE_Y:
645 wm_idx = 16;
646 break;
647 default:
648 break;
649 }
650 break;
651 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
652 switch (plane) {
653 case PLANE_Y:
654 wm_idx = 17;
655 break;
656 default:
657 break;
658 }
659 break;
660 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
661 switch (plane) {
662 case PLANE_Y:
663 wm_idx = 18;
664 break;
665 default:
666 break;
667 }
668 break;
669 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
670 switch (plane) {
671 case PLANE_Y:
672 wm_idx = 19;
673 break;
674 default:
675 break;
676 }
677 break;
678 default:
679 break;
680 }
681
682 return wm_idx;
683}
684
685static enum cam_vfe_bus_packer_format
686 cam_vfe_bus_get_packer_fmt(uint32_t out_fmt)
687{
688 switch (out_fmt) {
689 case CAM_FORMAT_NV21:
690 case CAM_FORMAT_NV12:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700691 case CAM_FORMAT_UBWC_NV12:
692 case CAM_FORMAT_UBWC_NV12_4R:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530693 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530694 case CAM_FORMAT_PLAIN16_16:
695 return PACKER_FMT_PLAIN_16_16BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530696 case CAM_FORMAT_PLAIN64:
697 return PACKER_FMT_PLAIN_64;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530698 case CAM_FORMAT_PLAIN8:
699 return PACKER_FMT_PLAIN_8;
700 case CAM_FORMAT_PLAIN16_10:
701 return PACKER_FMT_PLAIN_16_10BPP;
702 case CAM_FORMAT_PLAIN16_12:
703 return PACKER_FMT_PLAIN_16_12BPP;
704 case CAM_FORMAT_PLAIN16_14:
705 return PACKER_FMT_PLAIN_16_14BPP;
706 case CAM_FORMAT_PLAIN32_20:
707 return PACKER_FMT_PLAIN_32_20BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530708 case CAM_FORMAT_MIPI_RAW_6:
709 case CAM_FORMAT_MIPI_RAW_8:
710 case CAM_FORMAT_MIPI_RAW_10:
711 case CAM_FORMAT_MIPI_RAW_12:
712 case CAM_FORMAT_MIPI_RAW_14:
713 case CAM_FORMAT_MIPI_RAW_16:
714 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530715 case CAM_FORMAT_PLAIN16_8:
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530716 case CAM_FORMAT_PLAIN128:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530717 case CAM_FORMAT_PD8:
718 case CAM_FORMAT_PD10:
719 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700720 case CAM_FORMAT_UBWC_TP10:
721 case CAM_FORMAT_TP10:
722 return PACKER_FMT_TP_10;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530723 case CAM_FORMAT_ARGB_14:
724 return PACKER_FMT_ARGB_14;
Harsh Shaha1af8822017-05-11 22:06:36 -0700725 default:
726 return PACKER_FMT_MAX;
727 }
728}
729
730static int cam_vfe_bus_acquire_wm(
731 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
732 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700733 void *tasklet,
734 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700735 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
736 enum cam_vfe_bus_plane_type plane,
737 enum cam_isp_hw_split_id split_id,
738 uint32_t subscribe_irq,
739 struct cam_isp_resource_node **wm_res,
740 uint32_t *client_done_mask)
741{
742 uint32_t wm_idx = 0;
743 struct cam_isp_resource_node *wm_res_local = NULL;
744 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
745
746 *wm_res = NULL;
747 *client_done_mask = 0;
748
749 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
750 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
751 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700752 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700753 vfe_out_res_id, plane);
754 return -EINVAL;
755 }
756
757 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700758 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700759 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
760
761 rsrc_data = wm_res_local->res_priv;
762 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700763 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700764 rsrc_data->format = out_port_info->format;
765 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
766
767 rsrc_data->width = out_port_info->width;
768 rsrc_data->height = out_port_info->height;
Harsh Shahf7136392017-08-29 12:42:52 -0700769 CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index,
770 rsrc_data->width, rsrc_data->height);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700771
772 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700773 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Harsh Shahf7136392017-08-29 12:42:52 -0700774 switch (rsrc_data->format) {
775 case CAM_FORMAT_MIPI_RAW_6:
776 case CAM_FORMAT_MIPI_RAW_8:
777 case CAM_FORMAT_MIPI_RAW_10:
778 case CAM_FORMAT_MIPI_RAW_12:
779 case CAM_FORMAT_MIPI_RAW_14:
780 case CAM_FORMAT_MIPI_RAW_16:
781 case CAM_FORMAT_MIPI_RAW_20:
782 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
783 rsrc_data->height = 0;
784 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
785 rsrc_data->pack_fmt = 0x0;
786 rsrc_data->en_cfg = 0x3;
787 break;
788 case CAM_FORMAT_PLAIN8:
789 rsrc_data->en_cfg = 0x1;
790 rsrc_data->pack_fmt = 0x1;
791 rsrc_data->width = rsrc_data->width * 2;
792 rsrc_data->stride = rsrc_data->width;
793 break;
794 case CAM_FORMAT_PLAIN16_10:
795 rsrc_data->en_cfg = 0x1;
796 rsrc_data->pack_fmt = 0x2;
797 rsrc_data->width = rsrc_data->width * 2;
798 rsrc_data->stride = rsrc_data->width;
799 break;
800 case CAM_FORMAT_PLAIN16_12:
801 rsrc_data->en_cfg = 0x1;
802 rsrc_data->pack_fmt = 0x3;
803 rsrc_data->width = rsrc_data->width * 2;
804 rsrc_data->stride = rsrc_data->width;
805 break;
806 case CAM_FORMAT_PLAIN16_14:
807 rsrc_data->en_cfg = 0x1;
808 rsrc_data->pack_fmt = 0x4;
809 rsrc_data->width = rsrc_data->width * 2;
810 rsrc_data->stride = rsrc_data->width;
811 break;
812 case CAM_FORMAT_PLAIN16_16:
813 rsrc_data->en_cfg = 0x1;
814 rsrc_data->pack_fmt = 0x5;
815 rsrc_data->width = rsrc_data->width * 2;
816 rsrc_data->stride = rsrc_data->width;
817 break;
818 case CAM_FORMAT_PLAIN32_20:
819 rsrc_data->en_cfg = 0x1;
820 rsrc_data->pack_fmt = 0x9;
821 break;
822 case CAM_FORMAT_PLAIN64:
823 rsrc_data->en_cfg = 0x1;
824 rsrc_data->pack_fmt = 0xA;
825 break;
826 case CAM_FORMAT_PLAIN128:
827 rsrc_data->en_cfg = 0x1;
828 rsrc_data->pack_fmt = 0x0;
829 break;
830 default:
831 CAM_ERR(CAM_ISP, "Unsupported RDI format %d",
832 rsrc_data->format);
833 return -EINVAL;
834 }
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530835 } else if (rsrc_data->index < 5 ||
836 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700837 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
838 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700839 case CAM_FORMAT_UBWC_NV12_4R:
840 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700841 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
842 switch (plane) {
843 case PLANE_C:
844 rsrc_data->height /= 2;
845 break;
846 case PLANE_Y:
847 break;
848 default:
849 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
850 return -EINVAL;
851 }
852 break;
853 case CAM_FORMAT_UBWC_NV12:
854 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700855 /* Fall through for NV12 */
856 case CAM_FORMAT_NV21:
857 case CAM_FORMAT_NV12:
858 switch (plane) {
859 case PLANE_C:
860 rsrc_data->height /= 2;
861 break;
862 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700863 break;
864 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700865 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
866 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700867 }
868 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700869 case CAM_FORMAT_UBWC_TP10:
870 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700871 rsrc_data->width =
872 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
873 switch (plane) {
874 case PLANE_C:
875 rsrc_data->height /= 2;
876 break;
877 case PLANE_Y:
878 break;
879 default:
880 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
881 return -EINVAL;
882 }
883 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700884 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700885 rsrc_data->width =
886 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700887 switch (plane) {
888 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700889 rsrc_data->height /= 2;
890 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700891 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700892 break;
893 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700894 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
895 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700896 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700897 break;
898 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700899 CAM_ERR(CAM_ISP, "Invalid format %d\n",
900 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700901 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700902 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700903 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530904 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700905 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530906 rsrc_data->width = 0;
907 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530908 rsrc_data->stride = 1;
909 rsrc_data->en_cfg = 0x3;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530910 } else if (rsrc_data->index == 9) {
911 /* Write master 9 - Raw dump */
912 rsrc_data->width = rsrc_data->width * 2;
913 rsrc_data->stride = rsrc_data->width;
914 rsrc_data->en_cfg = 0x1;
915 } else {
916 /* Write master 5-6 DS ports, 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700917 rsrc_data->width = rsrc_data->width * 4;
918 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700919 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700920 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700921
922 *client_done_mask = (1 << wm_idx);
923 *wm_res = wm_res_local;
924
925 return 0;
926}
927
928static int cam_vfe_bus_release_wm(void *bus_priv,
929 struct cam_isp_resource_node *wm_res)
930{
931 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
932 wm_res->res_priv;
933
934 rsrc_data->irq_enabled = 0;
935 rsrc_data->offset = 0;
936 rsrc_data->width = 0;
937 rsrc_data->height = 0;
938 rsrc_data->stride = 0;
939 rsrc_data->format = 0;
940 rsrc_data->pack_fmt = 0;
941 rsrc_data->burst_len = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -0700942 rsrc_data->irq_subsample_period = 0;
943 rsrc_data->irq_subsample_pattern = 0;
944 rsrc_data->framedrop_period = 0;
945 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700946 rsrc_data->packer_cfg = 0;
947 rsrc_data->en_ubwc = 0;
948 rsrc_data->tile_cfg = 0;
949 rsrc_data->h_init = 0;
950 rsrc_data->v_init = 0;
951 rsrc_data->ubwc_meta_stride = 0;
952 rsrc_data->ubwc_mode_cfg = 0;
953 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700954 rsrc_data->init_cfg_done = false;
955 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700956 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700957
958 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700959 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
960
961 return 0;
962}
963
964static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
965{
966 int rc = 0;
967 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
968 wm_res->res_priv;
969 struct cam_vfe_bus_ver2_common_data *common_data =
970 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -0700971 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -0700972
Harsh Shah23557ae2017-05-13 18:14:34 -0700973 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
974 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -0700975 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
976
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700977 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -0700978 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700979 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -0700980 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700981 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -0700982 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700983
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530984 /* Configure stride for RDIs */
985 if (rsrc_data->index < 3)
986 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
987 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -0700988
Harsh Shah19f55812017-06-26 18:58:49 -0700989 /* Subscribe IRQ */
990 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700991 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -0700992 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
993 (1 << rsrc_data->index);
994 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
995 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
996 bus_irq_reg_mask, wm_res,
997 wm_res->top_half_handler,
998 cam_ife_mgr_do_tasklet_buf_done,
999 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
1000 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001001 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001002 rsrc_data->index);
1003 return -EFAULT;
1004 }
1005 }
1006
Junzhe Zou3d292562017-07-12 17:59:58 -07001007 /* enable ubwc if needed*/
1008 if (rsrc_data->en_ubwc) {
1009 cam_io_w_mb(0x1, common_data->mem_base +
1010 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
1011 }
1012
Harsh Shah19f55812017-06-26 18:58:49 -07001013 /* Enable WM */
1014 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
1015 rsrc_data->hw_regs->cfg);
1016
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001017 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001018 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001019 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001020 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001021 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001022 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001023 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
1024 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
1025 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001026
1027 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1028
1029 return rc;
1030}
1031
1032static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
1033{
1034 int rc = 0;
1035 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1036 wm_res->res_priv;
1037 struct cam_vfe_bus_ver2_common_data *common_data =
1038 rsrc_data->common_data;
1039
1040 /* Disble WM */
1041 cam_io_w_mb(0x0,
1042 common_data->mem_base + rsrc_data->hw_regs->cfg);
1043
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001044 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -07001045 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001046 if (rsrc_data->irq_enabled)
1047 rc = cam_irq_controller_unsubscribe_irq(
1048 common_data->bus_irq_controller,
1049 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001050
1051 /* Halt & Reset WM */
1052 cam_io_w_mb(BIT(rsrc_data->index),
1053 common_data->mem_base + common_data->common_reg->sw_reset);
1054
1055 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1056
1057 return rc;
1058}
1059
1060static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
1061 struct cam_irq_th_payload *th_payload)
1062{
Harsh Shah19f55812017-06-26 18:58:49 -07001063 int32_t rc;
1064 int i;
1065 struct cam_isp_resource_node *wm_res = NULL;
1066 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
1067 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1068
1069 wm_res = th_payload->handler_priv;
1070 if (!wm_res) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001071 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001072 return -ENODEV;
1073 }
1074
1075 rsrc_data = wm_res->res_priv;
1076
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001077 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1078 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001079
1080 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1081 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001082 CAM_ERR_RATE_LIMIT(CAM_ISP,
1083 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001084 return rc;
1085 }
1086
1087 cam_isp_hw_get_timestamp(&evt_payload->ts);
1088
1089 evt_payload->ctx = rsrc_data->ctx;
1090 evt_payload->core_index = rsrc_data->common_data->core_index;
1091 evt_payload->evt_id = evt_id;
1092
1093 for (i = 0; i < th_payload->num_registers; i++)
1094 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1095
1096 th_payload->evt_payload_priv = evt_payload;
1097
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001098 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001099 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001100}
1101
1102static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1103 void *evt_payload_priv)
1104{
1105 int rc = CAM_VFE_IRQ_STATUS_ERR;
1106 struct cam_isp_resource_node *wm_res = wm_node;
1107 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001108 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1109 (wm_res == NULL) ? NULL : wm_res->res_priv;
1110 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001111 uint32_t status_reg;
1112
Harsh Shah23557ae2017-05-13 18:14:34 -07001113 if (!evt_payload || !rsrc_data)
1114 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001115
Harsh Shah23557ae2017-05-13 18:14:34 -07001116 cam_ife_irq_regs = evt_payload->irq_reg_val;
1117 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1118
1119 if (status_reg & BIT(rsrc_data->index)) {
1120 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1121 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001122 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001123 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001124 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001125
1126 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001127 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001128 &evt_payload);
1129
1130 return rc;
1131}
1132
1133static int cam_vfe_bus_init_wm_resource(uint32_t index,
1134 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1135 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1136 struct cam_isp_resource_node *wm_res)
1137{
Harsh Shaha1af8822017-05-11 22:06:36 -07001138 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1139
1140 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1141 GFP_KERNEL);
1142 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001143 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001144 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001145 }
1146 wm_res->res_priv = rsrc_data;
1147
1148 rsrc_data->index = index;
1149 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1150 rsrc_data->common_data = &ver2_bus_priv->common_data;
1151
1152 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1153 INIT_LIST_HEAD(&wm_res->list);
1154
1155 wm_res->start = cam_vfe_bus_start_wm;
1156 wm_res->stop = cam_vfe_bus_stop_wm;
1157 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1158 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1159 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1160
Harsh Shah545df9a2017-06-16 16:43:17 -07001161 return 0;
1162}
1163
1164static int cam_vfe_bus_deinit_wm_resource(
1165 struct cam_isp_resource_node *wm_res)
1166{
1167 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1168
1169 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1170 INIT_LIST_HEAD(&wm_res->list);
1171
1172 wm_res->start = NULL;
1173 wm_res->stop = NULL;
1174 wm_res->top_half_handler = NULL;
1175 wm_res->bottom_half_handler = NULL;
1176 wm_res->hw_intf = NULL;
1177
1178 rsrc_data = wm_res->res_priv;
1179 wm_res->res_priv = NULL;
1180 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001181 CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001182 return -ENOMEM;
1183 }
1184 kfree(rsrc_data);
1185
1186 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001187}
1188
1189static void cam_vfe_bus_add_wm_to_comp_grp(
1190 struct cam_isp_resource_node *comp_grp,
1191 uint32_t composite_mask)
1192{
1193 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1194
1195 rsrc_data->composite_mask |= composite_mask;
1196}
1197
1198static void cam_vfe_bus_match_comp_grp(
1199 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1200 struct cam_isp_resource_node **comp_grp,
1201 uint32_t comp_grp_local_idx,
1202 uint32_t unique_id)
1203{
1204 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1205 struct cam_isp_resource_node *comp_grp_local = NULL;
1206
1207 list_for_each_entry(comp_grp_local,
1208 &ver2_bus_priv->used_comp_grp, list) {
1209 rsrc_data = comp_grp_local->res_priv;
1210 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1211 rsrc_data->unique_id == unique_id) {
1212 /* Match found */
1213 *comp_grp = comp_grp_local;
1214 return;
1215 }
1216 }
1217
1218 *comp_grp = NULL;
1219}
1220
1221static int cam_vfe_bus_acquire_comp_grp(
1222 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1223 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001224 void *tasklet,
1225 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001226 uint32_t unique_id,
1227 uint32_t is_dual,
1228 uint32_t is_master,
1229 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1230 struct cam_isp_resource_node **comp_grp)
1231{
1232 int rc = 0;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001233 uint32_t bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001234 struct cam_isp_resource_node *comp_grp_local = NULL;
1235 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1236
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001237 bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
1238 out_port_info->comp_grp_id);
1239 /* Perform match only if there is valid comp grp request */
1240 if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
1241 /* Check if matching comp_grp already acquired */
1242 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1243 bus_comp_grp_id, unique_id);
1244 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001245
1246 if (!comp_grp_local) {
1247 /* First find a free group */
1248 if (is_dual) {
1249 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001250 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001251 return -ENODEV;
1252 }
1253 comp_grp_local = list_first_entry(
1254 &ver2_bus_priv->free_dual_comp_grp,
1255 struct cam_isp_resource_node, list);
1256 rsrc_data = comp_grp_local->res_priv;
1257 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1258 dual_slave_core,
1259 comp_grp_local->hw_intf->hw_idx,
1260 &rsrc_data->intra_client_mask);
1261 } else {
1262 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001263 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001264 return -ENODEV;
1265 }
1266 comp_grp_local = list_first_entry(
1267 &ver2_bus_priv->free_comp_grp,
1268 struct cam_isp_resource_node, list);
1269 rsrc_data = comp_grp_local->res_priv;
1270 }
1271
1272 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001273 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001274 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1275
1276 rsrc_data->is_master = is_master;
1277 rsrc_data->composite_mask = 0;
1278 rsrc_data->unique_id = unique_id;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001279 rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001280
1281 list_add_tail(&comp_grp_local->list,
1282 &ver2_bus_priv->used_comp_grp);
1283
1284 } else {
1285 rsrc_data = comp_grp_local->res_priv;
1286 /* Do not support runtime change in composite mask */
1287 if (comp_grp_local->res_state ==
1288 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001289 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001290 comp_grp_local->res_state,
1291 rsrc_data->comp_grp_type);
1292 return -EBUSY;
1293 }
1294 }
1295
Harsh Shah19f55812017-06-26 18:58:49 -07001296 rsrc_data->ctx = ctx;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001297 rsrc_data->acquire_dev_cnt++;
Harsh Shaha1af8822017-05-11 22:06:36 -07001298 *comp_grp = comp_grp_local;
1299
1300 return rc;
1301}
1302
1303static int cam_vfe_bus_release_comp_grp(
1304 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1305 struct cam_isp_resource_node *in_comp_grp)
1306{
1307 struct cam_isp_resource_node *comp_grp = NULL;
1308 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1309 int match_found = 0;
1310
1311 if (!in_comp_grp) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001312 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
Harsh Shaha1af8822017-05-11 22:06:36 -07001313 return -EINVAL;
1314 }
1315
1316 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001317 CAM_ERR(CAM_ISP, "Already released Comp Grp");
Harsh Shaha1af8822017-05-11 22:06:36 -07001318 return 0;
1319 }
1320
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001321 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
1322 CAM_ERR(CAM_ISP, "Invalid State %d",
1323 in_comp_grp->res_state);
1324 return -EBUSY;
1325 }
1326
Harsh Shaha1af8822017-05-11 22:06:36 -07001327 in_rsrc_data = in_comp_grp->res_priv;
1328
1329 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1330 if (comp_grp == in_comp_grp) {
1331 match_found = 1;
1332 break;
1333 }
1334 }
1335
1336 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001337 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001338 in_rsrc_data->comp_grp_type);
1339 return -ENODEV;
1340 }
1341
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001342 in_rsrc_data->acquire_dev_cnt--;
1343 if (in_rsrc_data->acquire_dev_cnt == 0) {
1344 list_del(&comp_grp->list);
Harsh Shaha1af8822017-05-11 22:06:36 -07001345
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001346 in_rsrc_data->unique_id = 0;
1347 in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
1348 in_rsrc_data->composite_mask = 0;
1349 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
Harsh Shaha1af8822017-05-11 22:06:36 -07001350
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001351 comp_grp->tasklet_info = NULL;
1352 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
Harsh Shaha1af8822017-05-11 22:06:36 -07001353
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001354 if (in_rsrc_data->comp_grp_type >=
1355 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1356 in_rsrc_data->comp_grp_type <=
1357 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1358 list_add_tail(&comp_grp->list,
1359 &ver2_bus_priv->free_dual_comp_grp);
1360 else if (in_rsrc_data->comp_grp_type >=
1361 CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1362 in_rsrc_data->comp_grp_type <=
1363 CAM_VFE_BUS_VER2_COMP_GRP_5)
1364 list_add_tail(&comp_grp->list,
1365 &ver2_bus_priv->free_comp_grp);
1366 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001367
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001368 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001369}
1370
1371static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1372{
1373 int rc = 0;
1374 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1375 comp_grp->res_priv;
1376 struct cam_vfe_bus_ver2_common_data *common_data =
1377 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001378 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001379
1380 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1381 rsrc_data->hw_regs->comp_mask);
1382
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001383 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1384 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1385 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001386
1387 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1388 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1389 rsrc_data->is_master) {
1390 int dual_comp_grp = (rsrc_data->comp_grp_type -
1391 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1392 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1393 common_data->common_reg->dual_master_comp_cfg);
1394
1395 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1396 intra_client_en |=
1397 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1398
1399 cam_io_w_mb(intra_client_en, common_data->mem_base +
1400 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001401
1402 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1403 } else {
1404 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1405 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1406 (1 << (rsrc_data->comp_grp_type + 5));
1407 }
1408
1409 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001410 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001411 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1412 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1413 bus_irq_reg_mask, comp_grp,
1414 comp_grp->top_half_handler,
1415 cam_ife_mgr_do_tasklet_buf_done,
1416 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1417 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001418 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001419 rsrc_data->comp_grp_type);
1420 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001421 }
1422
1423 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001424
Harsh Shaha1af8822017-05-11 22:06:36 -07001425 return rc;
1426}
1427
1428static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1429{
1430 int rc = 0;
1431 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1432 comp_grp->res_priv;
1433 struct cam_vfe_bus_ver2_common_data *common_data =
1434 rsrc_data->common_data;
1435
1436 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001437 rc = cam_irq_controller_unsubscribe_irq(
1438 common_data->bus_irq_controller,
1439 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001440
1441 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1442 rsrc_data->hw_regs->comp_mask);
1443 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1444 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1445 rsrc_data->is_master) {
1446 int dual_comp_grp = (rsrc_data->comp_grp_type -
1447 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1448 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1449 common_data->common_reg->dual_master_comp_cfg);
1450
1451 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1452 intra_client_en &=
1453 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1454
1455 cam_io_w_mb(intra_client_en, common_data->mem_base +
1456 common_data->common_reg->dual_master_comp_cfg);
1457 }
1458
1459 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1460
1461 return rc;
1462}
1463
1464static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1465 struct cam_irq_th_payload *th_payload)
1466{
Harsh Shah19f55812017-06-26 18:58:49 -07001467 int32_t rc;
1468 int i;
1469 struct cam_isp_resource_node *comp_grp = NULL;
1470 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1471 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1472
1473 comp_grp = th_payload->handler_priv;
1474 if (!comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001475 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001476 return -ENODEV;
1477 }
1478
1479 rsrc_data = comp_grp->res_priv;
1480
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001481 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1482 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001483
1484 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1485 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001486 CAM_ERR_RATE_LIMIT(CAM_ISP,
1487 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001488 return rc;
1489 }
1490
1491 cam_isp_hw_get_timestamp(&evt_payload->ts);
1492
1493 evt_payload->ctx = rsrc_data->ctx;
1494 evt_payload->core_index = rsrc_data->common_data->core_index;
1495 evt_payload->evt_id = evt_id;
1496
1497 for (i = 0; i < th_payload->num_registers; i++)
1498 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1499
1500 th_payload->evt_payload_priv = evt_payload;
1501
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001502 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001503 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001504}
1505
1506static int cam_vfe_bus_handle_comp_done_bottom_half(
1507 void *handler_priv,
1508 void *evt_payload_priv)
1509{
1510 int rc = CAM_VFE_IRQ_STATUS_ERR;
1511 struct cam_isp_resource_node *comp_grp = handler_priv;
1512 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1513 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001514 uint32_t *cam_ife_irq_regs;
1515 uint32_t status_reg;
1516 uint32_t comp_err_reg;
1517 uint32_t comp_grp_id;
1518
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001519 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001520
Harsh Shah23557ae2017-05-13 18:14:34 -07001521 if (!evt_payload)
1522 return rc;
1523
1524 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001525
Harsh Shaha1af8822017-05-11 22:06:36 -07001526 switch (rsrc_data->comp_grp_type) {
1527 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1528 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1529 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1530 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1531 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1532 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001533 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001534 CAM_VFE_BUS_VER2_COMP_GRP_0);
1535
1536 /* Check for Regular composite error */
1537 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1538
1539 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1540 if ((status_reg & BIT(11)) &&
1541 (comp_err_reg & rsrc_data->composite_mask)) {
1542 /* Check for Regular composite error */
1543 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1544 break;
1545 }
1546
1547 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1548 /* Check for Regular composite Overwrite */
1549 if ((status_reg & BIT(12)) &&
1550 (comp_err_reg & rsrc_data->composite_mask)) {
1551 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1552 break;
1553 }
1554
Harsh Shah23557ae2017-05-13 18:14:34 -07001555 /* Regular Composite SUCCESS */
1556 if (status_reg & BIT(comp_grp_id + 5)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001557 rsrc_data->irq_trigger_cnt++;
1558 if (rsrc_data->irq_trigger_cnt ==
1559 rsrc_data->acquire_dev_cnt) {
1560 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1561 ~BIT(comp_grp_id + 5);
1562 rsrc_data->irq_trigger_cnt = 0;
1563 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001564 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001565 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001566
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001567 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001568 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001569 break;
1570
1571 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1572 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1573 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1574 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1575 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1576 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001577 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001578 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1579
1580 /* Check for DUAL composite error */
1581 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1582
1583 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1584 if ((status_reg & BIT(6)) &&
1585 (comp_err_reg & rsrc_data->composite_mask)) {
1586 /* Check for DUAL composite error */
1587 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1588 break;
1589 }
1590
1591 /* Check for Dual composite Overwrite */
1592 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1593 if ((status_reg & BIT(7)) &&
1594 (comp_err_reg & rsrc_data->composite_mask)) {
1595 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1596 break;
1597 }
1598
Harsh Shah23557ae2017-05-13 18:14:34 -07001599 /* DUAL Composite SUCCESS */
1600 if (status_reg & BIT(comp_grp_id)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001601 rsrc_data->irq_trigger_cnt++;
1602 if (rsrc_data->irq_trigger_cnt ==
1603 rsrc_data->acquire_dev_cnt) {
1604 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1605 ~BIT(comp_grp_id + 5);
1606 rsrc_data->irq_trigger_cnt = 0;
1607 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001608 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001609 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001610
1611 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001612 default:
1613 rc = CAM_VFE_IRQ_STATUS_ERR;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001614 CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001615 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001616 break;
1617 }
1618
1619 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001620 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001621 &evt_payload);
1622
1623 return rc;
1624}
1625
1626static int cam_vfe_bus_init_comp_grp(uint32_t index,
1627 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1628 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1629 struct cam_isp_resource_node *comp_grp)
1630{
Harsh Shah545df9a2017-06-16 16:43:17 -07001631 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001632
1633 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1634 GFP_KERNEL);
1635 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001636 CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001637 return -ENOMEM;
1638 }
1639 comp_grp->res_priv = rsrc_data;
1640
1641 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1642 INIT_LIST_HEAD(&comp_grp->list);
1643
1644 rsrc_data->comp_grp_type = index;
1645 rsrc_data->common_data = &ver2_bus_priv->common_data;
1646 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1647 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1648
Harsh Shaha1af8822017-05-11 22:06:36 -07001649 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1650 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1651 list_add_tail(&comp_grp->list,
1652 &ver2_bus_priv->free_dual_comp_grp);
1653 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1654 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1655 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1656
1657 comp_grp->start = cam_vfe_bus_start_comp_grp;
1658 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1659 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1660 comp_grp->bottom_half_handler =
1661 cam_vfe_bus_handle_comp_done_bottom_half;
1662 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1663
1664 return 0;
1665}
1666
Harsh Shah545df9a2017-06-16 16:43:17 -07001667static int cam_vfe_bus_deinit_comp_grp(
1668 struct cam_isp_resource_node *comp_grp)
1669{
1670 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1671 comp_grp->res_priv;
1672
1673 comp_grp->start = NULL;
1674 comp_grp->stop = NULL;
1675 comp_grp->top_half_handler = NULL;
1676 comp_grp->bottom_half_handler = NULL;
1677 comp_grp->hw_intf = NULL;
1678
1679 list_del_init(&comp_grp->list);
1680 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1681
1682 comp_grp->res_priv = NULL;
1683
1684 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001685 CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001686 return -ENODEV;
1687 }
1688 kfree(rsrc_data);
1689
1690 return 0;
1691}
1692
Harsh Shah19f55812017-06-26 18:58:49 -07001693static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1694 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001695{
1696 int rc = -ENODEV;
1697 int i;
1698 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1699 uint32_t format;
Harsh Shahea526f82017-09-25 14:47:32 -07001700 int num_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07001701 uint32_t subscribe_irq;
1702 uint32_t client_done_mask;
1703 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1704 struct cam_vfe_acquire_args *acq_args = acquire_args;
1705 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1706 struct cam_isp_resource_node *rsrc_node = NULL;
1707 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1708
1709 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001710 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001711 return -EINVAL;
1712 }
1713
1714 out_acquire_args = &acq_args->vfe_out;
1715 format = out_acquire_args->out_port_info->format;
1716
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001717 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001718 out_acquire_args->out_port_info->res_type);
1719
1720 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1721 out_acquire_args->out_port_info->res_type);
1722 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1723 return -ENODEV;
1724
1725 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1726 if (num_wm < 1)
1727 return -EINVAL;
1728
1729 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1730 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001731 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001732 vfe_out_res_id, rsrc_node->res_state);
1733 return -EBUSY;
1734 }
1735
1736 rsrc_data = rsrc_node->res_priv;
1737 rsrc_data->num_wm = num_wm;
1738 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1739 rsrc_node->tasklet_info = acq_args->tasklet;
1740 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1741 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1742
1743 /* Reserve Composite Group */
1744 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1745 CAM_ISP_RES_COMP_GROUP_NONE &&
1746 out_acquire_args->out_port_info->comp_grp_id <
1747 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1748 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1749 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001750 acq_args->tasklet,
1751 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001752 out_acquire_args->unique_id,
1753 out_acquire_args->is_dual,
1754 out_acquire_args->is_master,
1755 out_acquire_args->dual_slave_core,
1756 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001757 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001758 CAM_ERR(CAM_ISP,
1759 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001760 rsrc_data->common_data->core_index,
1761 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001762 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001763 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001764
1765 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001766 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001767 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001768 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001769
1770 /* Reserve WM */
1771 for (i = 0; i < num_wm; i++) {
1772 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1773 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001774 acq_args->tasklet,
1775 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001776 vfe_out_res_id,
1777 i,
1778 out_acquire_args->split_id,
1779 subscribe_irq,
1780 &rsrc_data->wm_res[i],
1781 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001782 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001783 CAM_ERR(CAM_ISP,
1784 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001785 rsrc_data->common_data->core_index,
1786 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001787 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001788 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001789
1790 if (rsrc_data->comp_grp)
1791 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1792 client_done_mask);
1793 }
1794
1795 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1796 out_acquire_args->rsrc_node = rsrc_node;
1797
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001798 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001799 return rc;
1800
1801release_wm:
1802 for (i--; i >= 0; i--)
1803 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1804
1805 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1806 rsrc_data->comp_grp);
1807
1808 return rc;
1809}
1810
Harsh Shah19f55812017-06-26 18:58:49 -07001811static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1812 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001813{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001814 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001815 struct cam_isp_resource_node *vfe_out = NULL;
1816 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1817
1818 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001819 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001820 bus_priv, release_args);
1821 return -EINVAL;
1822 }
1823
1824 vfe_out = release_args;
1825 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001826
Harsh Shaha1af8822017-05-11 22:06:36 -07001827 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001828 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001829 vfe_out->res_state);
1830 }
1831
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001832 for (i = 0; i < rsrc_data->num_wm; i++)
1833 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1834 rsrc_data->num_wm = 0;
1835
1836 if (rsrc_data->comp_grp)
1837 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1838 rsrc_data->comp_grp = NULL;
1839
1840 vfe_out->tasklet_info = NULL;
1841 vfe_out->cdm_ops = NULL;
1842 rsrc_data->cdm_util_ops = NULL;
1843
Harsh Shaha1af8822017-05-11 22:06:36 -07001844 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1845 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1846
1847 return 0;
1848}
1849
Harsh Shah19f55812017-06-26 18:58:49 -07001850static int cam_vfe_bus_start_vfe_out(
1851 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001852{
1853 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001854 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1855 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1856
1857 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001858 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001859 return -EINVAL;
1860 }
1861
1862 rsrc_data = vfe_out->res_priv;
1863 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001864
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001865 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001866
1867 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001868 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001869 vfe_out->res_state);
1870 return -EACCES;
1871 }
1872
1873 for (i = 0; i < rsrc_data->num_wm; i++)
1874 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1875
1876 if (rsrc_data->comp_grp)
1877 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1878
Harsh Shaha1af8822017-05-11 22:06:36 -07001879 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1880 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1881 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1882 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1883 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1884 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001885 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1886 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1887 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1888 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1889 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1890 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1891 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1892 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1893 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1894
Harsh Shah23557ae2017-05-13 18:14:34 -07001895 /* no clock gating at bus input */
1896 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1897
1898 /* BUS_WR_TEST_BUS_CTRL */
1899 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
1900
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05301901 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07001902 return rc;
1903}
1904
Harsh Shah19f55812017-06-26 18:58:49 -07001905static int cam_vfe_bus_stop_vfe_out(
1906 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001907{
1908 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001909 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1910
1911 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001912 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001913 return -EINVAL;
1914 }
1915
1916 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001917
1918 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
1919 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
1920 return rc;
1921 }
1922
1923 if (rsrc_data->comp_grp)
1924 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
1925
1926 for (i = 0; i < rsrc_data->num_wm; i++)
1927 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
1928
Harsh Shaha1af8822017-05-11 22:06:36 -07001929
1930 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1931 return rc;
1932}
1933
1934static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
1935 struct cam_irq_th_payload *th_payload)
1936{
1937 return -EPERM;
1938}
1939
1940static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
1941 void *handler_priv,
1942 void *evt_payload_priv)
1943{
1944 int rc = -EINVAL;
1945 struct cam_isp_resource_node *vfe_out = handler_priv;
1946 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1947
1948 /*
1949 * If this resource has Composite Group then we only handle
1950 * Composite done. We acquire Composite if number of WM > 1.
1951 * So Else case is only one individual buf_done = WM[0].
1952 */
1953 if (rsrc_data->comp_grp) {
1954 rc = rsrc_data->comp_grp->bottom_half_handler(
1955 rsrc_data->comp_grp, evt_payload_priv);
1956 } else {
1957 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07001958 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07001959 }
1960
1961 return rc;
1962}
1963
1964static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
1965 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1966 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1967 struct cam_isp_resource_node *vfe_out)
1968{
1969 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1970 int rc = 0;
1971
1972 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
1973 GFP_KERNEL);
1974 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001975 CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001976 rc = -ENOMEM;
1977 return rc;
1978 }
1979 vfe_out->res_priv = rsrc_data;
1980
1981 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
1982 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1983 INIT_LIST_HEAD(&vfe_out->list);
1984
1985 rsrc_data->out_type = index;
1986 rsrc_data->common_data = &ver2_bus_priv->common_data;
1987 rsrc_data->max_width =
1988 ver2_hw_info->vfe_out_hw_info[index].max_width;
1989 rsrc_data->max_height =
1990 ver2_hw_info->vfe_out_hw_info[index].max_height;
1991
1992 vfe_out->start = cam_vfe_bus_start_vfe_out;
1993 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
1994 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
1995 vfe_out->bottom_half_handler =
1996 cam_vfe_bus_handle_vfe_out_done_bottom_half;
1997 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
1998
1999 return 0;
2000}
2001
Harsh Shah545df9a2017-06-16 16:43:17 -07002002static int cam_vfe_bus_deinit_vfe_out_resource(
2003 struct cam_isp_resource_node *vfe_out)
2004{
2005 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2006
2007 vfe_out->start = NULL;
2008 vfe_out->stop = NULL;
2009 vfe_out->top_half_handler = NULL;
2010 vfe_out->bottom_half_handler = NULL;
2011 vfe_out->hw_intf = NULL;
2012
2013 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
2014 INIT_LIST_HEAD(&vfe_out->list);
2015 vfe_out->res_priv = NULL;
2016
2017 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002018 CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002019 return -ENOMEM;
2020 }
2021 kfree(rsrc_data);
2022
2023 return 0;
2024}
2025
Harsh Shaha1af8822017-05-11 22:06:36 -07002026static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
2027 struct cam_irq_th_payload *th_payload)
2028{
Harsh Shaha1af8822017-05-11 22:06:36 -07002029 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002030
Harsh Shah19f55812017-06-26 18:58:49 -07002031 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002032 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07002033 return cam_irq_controller_handle_irq(evt_id,
2034 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07002035}
2036
2037static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
2038 uint32_t arg_size)
2039{
2040 struct cam_vfe_bus_ver2_priv *bus_priv;
2041 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002042 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07002043 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2044 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002045 uint32_t *reg_val_pair;
2046 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07002047 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07002048
2049 /*
2050 * Need the entire buf io config so we can get the stride info
2051 * for the wm.
2052 */
2053
2054 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2055 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
2056
2057 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2058 update_buf->cdm.res->res_priv;
2059
2060 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002061 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07002062 return -EINVAL;
2063 }
2064
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002065 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002066 CAM_ERR(CAM_ISP,
2067 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002068 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07002069 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07002070 }
2071
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002072 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2073 io_cfg = update_buf->io_cfg;
2074
2075 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07002076 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002077 CAM_ERR(CAM_ISP,
2078 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07002079 j, MAX_REG_VAL_PAIR_SIZE);
2080 return -ENOMEM;
2081 }
2082
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002083 wm_data = vfe_out_data->wm_res[i]->res_priv;
2084
2085 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302086 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
2087 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002088 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2089 wm_data->hw_regs->stride,
2090 io_cfg->planes[i].plane_stride);
2091 wm_data->stride = io_cfg->planes[i].plane_stride;
2092 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002093 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002094
2095 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002096 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002097 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2098 wm_data->hw_regs->framedrop_pattern,
2099 io_cfg->framedrop_pattern);
2100 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
2101 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002102 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2103 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002104
2105 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002106 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002107 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2108 wm_data->hw_regs->framedrop_period,
2109 io_cfg->framedrop_period);
2110 wm_data->framedrop_period = io_cfg->framedrop_period;
2111 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002112 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2113 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002114
2115 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002116 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002117 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2118 wm_data->hw_regs->irq_subsample_period,
2119 io_cfg->subsample_period);
2120 wm_data->irq_subsample_period =
2121 io_cfg->subsample_period;
2122 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002123 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002124 wm_data->irq_subsample_period);
2125
2126 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002127 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002128 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2129 wm_data->hw_regs->irq_subsample_pattern,
2130 io_cfg->subsample_pattern);
2131 wm_data->irq_subsample_pattern =
2132 io_cfg->subsample_pattern;
2133 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002134 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002135 wm_data->irq_subsample_pattern);
2136
2137 if (wm_data->en_ubwc) {
2138 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002139 CAM_ERR(CAM_ISP,
2140 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002141 return -EINVAL;
2142 }
2143 if (wm_data->packer_cfg !=
2144 io_cfg->planes[i].packer_config ||
2145 !wm_data->init_cfg_done) {
2146 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2147 wm_data->hw_regs->packer_cfg,
2148 io_cfg->planes[i].packer_config);
2149 wm_data->packer_cfg =
2150 io_cfg->planes[i].packer_config;
2151 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002152 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2153 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002154
2155 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
2156 || !wm_data->init_cfg_done) {
2157 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2158 wm_data->hw_regs->ubwc_regs->tile_cfg,
2159 io_cfg->planes[i].tile_config);
2160 wm_data->tile_cfg =
2161 io_cfg->planes[i].tile_config;
2162 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002163 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002164
2165 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2166 !wm_data->init_cfg_done) {
2167 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2168 wm_data->hw_regs->ubwc_regs->h_init,
2169 io_cfg->planes[i].h_init);
2170 wm_data->h_init = io_cfg->planes[i].h_init;
2171 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002172 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002173
2174 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2175 !wm_data->init_cfg_done) {
2176 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2177 wm_data->hw_regs->ubwc_regs->v_init,
2178 io_cfg->planes[i].v_init);
2179 wm_data->v_init = io_cfg->planes[i].v_init;
2180 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002181 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002182
2183 if (wm_data->ubwc_meta_stride !=
2184 io_cfg->planes[i].meta_stride ||
2185 !wm_data->init_cfg_done) {
2186 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2187 wm_data->hw_regs->ubwc_regs->
2188 meta_stride,
2189 io_cfg->planes[i].meta_stride);
2190 wm_data->ubwc_meta_stride =
2191 io_cfg->planes[i].meta_stride;
2192 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002193 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2194 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002195
2196 if (wm_data->ubwc_mode_cfg !=
2197 io_cfg->planes[i].mode_config ||
2198 !wm_data->init_cfg_done) {
2199 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2200 wm_data->hw_regs->ubwc_regs->mode_cfg,
2201 io_cfg->planes[i].mode_config);
2202 wm_data->ubwc_mode_cfg =
2203 io_cfg->planes[i].mode_config;
2204 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002205 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2206 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002207
2208 if (wm_data->ubwc_meta_offset !=
2209 io_cfg->planes[i].meta_offset ||
2210 !wm_data->init_cfg_done) {
2211 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2212 wm_data->hw_regs->ubwc_regs->
2213 meta_offset,
2214 io_cfg->planes[i].meta_offset);
2215 wm_data->ubwc_meta_offset =
2216 io_cfg->planes[i].meta_offset;
2217 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002218 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002219 wm_data->ubwc_meta_offset);
2220
2221 /* UBWC meta address */
2222 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2223 wm_data->hw_regs->ubwc_regs->meta_addr,
2224 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002225 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002226 update_buf->image_buf[i]);
2227 }
2228
2229 /* WM Image address */
2230 if (wm_data->en_ubwc)
2231 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2232 wm_data->hw_regs->image_addr,
2233 (update_buf->image_buf[i] +
2234 io_cfg->planes[i].meta_size));
2235 else
2236 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2237 wm_data->hw_regs->image_addr,
2238 update_buf->image_buf[i]);
2239
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002240 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002241
Junzhe Zou193d78c2017-05-16 15:10:54 -07002242 frame_inc = io_cfg->planes[i].plane_stride *
2243 io_cfg->planes[i].slice_height;
2244 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2245 wm_data->hw_regs->frame_inc, frame_inc);
2246
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002247 /* enable the WM */
2248 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2249 wm_data->hw_regs->cfg,
2250 wm_data->en_cfg);
2251
2252 /* set initial configuration done */
2253 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002254 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002255 }
2256
2257 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002258
2259 /* cdm util returns dwords, need to convert to bytes */
2260 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002261 CAM_ERR(CAM_ISP,
2262 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002263 update_buf->cdm.size, size);
2264 return -ENOMEM;
2265 }
2266
Harsh Shaha1af8822017-05-11 22:06:36 -07002267 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002268 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2269
Harsh Shaha1af8822017-05-11 22:06:36 -07002270 /* cdm util returns dwords, need to convert to bytes */
2271 update_buf->cdm.used_bytes = size * 4;
2272
2273 return 0;
2274}
2275
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002276static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2277 uint32_t arg_size)
2278{
2279 struct cam_vfe_bus_ver2_priv *bus_priv;
2280 struct cam_isp_hw_get_hfr_update *update_hfr;
2281 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2282 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2283 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2284 uint32_t *reg_val_pair;
2285 uint32_t i, j, size = 0;
2286
2287 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2288 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2289
2290 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2291 update_hfr->cdm.res->res_priv;
2292
2293 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2294 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2295 return -EINVAL;
2296 }
2297
2298 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2299 hfr_cfg = update_hfr->io_hfr_cfg;
2300
2301 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2302 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2303 CAM_ERR(CAM_ISP,
2304 "reg_val_pair %d exceeds the array limit %lu",
2305 j, MAX_REG_VAL_PAIR_SIZE);
2306 return -ENOMEM;
2307 }
2308
2309 wm_data = vfe_out_data->wm_res[i]->res_priv;
2310
2311 if ((wm_data->framedrop_pattern !=
2312 hfr_cfg->framedrop_pattern) ||
2313 !wm_data->hfr_cfg_done) {
2314 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2315 wm_data->hw_regs->framedrop_pattern,
2316 hfr_cfg->framedrop_pattern);
2317 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2318 }
2319 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2320 wm_data->framedrop_pattern);
2321
2322 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2323 !wm_data->hfr_cfg_done) {
2324 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2325 wm_data->hw_regs->framedrop_period,
2326 hfr_cfg->framedrop_period);
2327 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2328 }
2329 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2330 wm_data->framedrop_period);
2331
2332 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2333 || !wm_data->hfr_cfg_done) {
2334 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2335 wm_data->hw_regs->irq_subsample_period,
2336 hfr_cfg->subsample_period);
2337 wm_data->irq_subsample_period =
2338 hfr_cfg->subsample_period;
2339 }
2340 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2341 wm_data->irq_subsample_period);
2342
2343 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2344 || !wm_data->hfr_cfg_done) {
2345 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2346 wm_data->hw_regs->irq_subsample_pattern,
2347 hfr_cfg->subsample_pattern);
2348 wm_data->irq_subsample_pattern =
2349 hfr_cfg->subsample_pattern;
2350 }
2351 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2352 wm_data->irq_subsample_pattern);
2353
2354 /* set initial configuration done */
2355 if (!wm_data->hfr_cfg_done)
2356 wm_data->hfr_cfg_done = true;
2357 }
2358
2359 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2360
2361 /* cdm util returns dwords, need to convert to bytes */
2362 if ((size * 4) > update_hfr->cdm.size) {
2363 CAM_ERR(CAM_ISP,
2364 "Failed! Buf size:%d insufficient, expected size:%d",
2365 update_hfr->cdm.size, size);
2366 return -ENOMEM;
2367 }
2368
2369 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2370 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2371
2372 /* cdm util returns dwords, need to convert to bytes */
2373 update_hfr->cdm.used_bytes = size * 4;
2374
2375 return 0;
2376}
2377
Harsh Shah19f55812017-06-26 18:58:49 -07002378static int cam_vfe_bus_start_hw(void *hw_priv,
2379 void *start_hw_args, uint32_t arg_size)
2380{
2381 return cam_vfe_bus_start_vfe_out(hw_priv);
2382}
2383
2384static int cam_vfe_bus_stop_hw(void *hw_priv,
2385 void *stop_hw_args, uint32_t arg_size)
2386{
2387 return cam_vfe_bus_stop_vfe_out(hw_priv);
2388}
2389
2390static int cam_vfe_bus_init_hw(void *hw_priv,
2391 void *init_hw_args, uint32_t arg_size)
2392{
2393 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2394 uint32_t top_irq_reg_mask[2] = {0};
2395
2396 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002397 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002398 return -EINVAL;
2399 }
2400
2401 top_irq_reg_mask[0] = (1 << 9);
2402
2403 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2404 bus_priv->common_data.vfe_irq_controller,
2405 CAM_IRQ_PRIORITY_2,
2406 top_irq_reg_mask,
2407 bus_priv,
2408 cam_vfe_bus_ver2_handle_irq,
2409 NULL,
2410 NULL,
2411 NULL);
2412
2413 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002414 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002415 return -EFAULT;
2416 }
2417
2418 return 0;
2419}
2420
2421static int cam_vfe_bus_deinit_hw(void *hw_priv,
2422 void *deinit_hw_args, uint32_t arg_size)
2423{
2424 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2425 int rc;
2426
2427 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002428 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002429 return -EINVAL;
2430 }
2431
2432 rc = cam_irq_controller_unsubscribe_irq(
2433 bus_priv->common_data.vfe_irq_controller,
2434 bus_priv->irq_handle);
2435 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002436 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002437
2438 return rc;
2439}
2440
Harsh Shaha1af8822017-05-11 22:06:36 -07002441static int cam_vfe_bus_process_cmd(void *priv,
2442 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2443{
2444 int rc = -EINVAL;
2445
2446 if (!priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002447 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
Harsh Shaha1af8822017-05-11 22:06:36 -07002448 return -EINVAL;
2449 }
2450
2451 switch (cmd_type) {
2452 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2453 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2454 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002455 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2456 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2457 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002458 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002459 CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
Harsh Shaha1af8822017-05-11 22:06:36 -07002460 cmd_type);
2461 break;
2462 }
2463
2464 return rc;
2465}
2466
2467int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002468 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002469 struct cam_hw_intf *hw_intf,
2470 void *bus_hw_info,
2471 void *vfe_irq_controller,
2472 struct cam_vfe_bus **vfe_bus)
2473{
2474 int i, rc = 0;
2475 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2476 struct cam_vfe_bus *vfe_bus_local;
2477 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2478
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002479 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002480
Harsh Shah19f55812017-06-26 18:58:49 -07002481 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002482 CAM_ERR(CAM_ISP,
2483 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2484 soc_info, hw_intf, bus_hw_info);
2485 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002486 rc = -EINVAL;
2487 goto end;
2488 }
2489
Harsh Shaha1af8822017-05-11 22:06:36 -07002490 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2491 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002492 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002493 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002494 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002495 }
2496
2497 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2498 GFP_KERNEL);
2499 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002500 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002501 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002502 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002503 }
2504 vfe_bus_local->bus_priv = bus_priv;
2505
Harsh Shah19f55812017-06-26 18:58:49 -07002506 bus_priv->common_data.core_index = soc_info->index;
2507 bus_priv->common_data.mem_base =
2508 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002509 bus_priv->common_data.hw_intf = hw_intf;
2510 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2511 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
2512
Harsh Shah19f55812017-06-26 18:58:49 -07002513 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2514 &ver2_hw_info->common_reg.irq_reg_info,
2515 &bus_priv->common_data.bus_irq_controller);
2516 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002517 CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002518 goto free_bus_priv;
2519 }
2520
Harsh Shaha1af8822017-05-11 22:06:36 -07002521 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2522 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2523 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2524
2525 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2526 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2527 &bus_priv->bus_client[i]);
2528 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002529 CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002530 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002531 }
2532 }
2533
2534 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2535 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2536 &bus_priv->comp_grp[i]);
2537 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002538 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002539 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002540 }
2541 }
2542
2543 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2544 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2545 &bus_priv->vfe_out[i]);
2546 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002547 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002548 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002549 }
2550 }
2551
Harsh Shah19f55812017-06-26 18:58:49 -07002552 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2553 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2554 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2555 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2556 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002557 }
2558
Harsh Shah19f55812017-06-26 18:58:49 -07002559 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2560 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2561 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2562 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2563 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2564 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2565 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002566 vfe_bus_local->bottom_half_handler = NULL;
Harsh Shah19f55812017-06-26 18:58:49 -07002567 vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002568
2569 *vfe_bus = vfe_bus_local;
2570
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002571 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002572 return rc;
2573
Harsh Shah545df9a2017-06-16 16:43:17 -07002574deinit_vfe_out:
2575 if (i < 0)
2576 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2577 for (--i; i >= 0; i--)
2578 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2579
2580deinit_comp_grp:
2581 if (i < 0)
2582 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2583 for (--i; i >= 0; i--)
2584 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2585
2586deinit_wm:
2587 if (i < 0)
2588 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2589 for (--i; i >= 0; i--)
2590 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2591
Harsh Shah19f55812017-06-26 18:58:49 -07002592free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002593 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002594
2595free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002596 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002597
2598end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002599 return rc;
2600}
Harsh Shah545df9a2017-06-16 16:43:17 -07002601
2602int cam_vfe_bus_ver2_deinit(
2603 struct cam_vfe_bus **vfe_bus)
2604{
2605 int i, rc = 0;
2606 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2607 struct cam_vfe_bus *vfe_bus_local;
2608
2609 if (!vfe_bus || !*vfe_bus) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002610 CAM_ERR(CAM_ISP, "Error! Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002611 return -EINVAL;
2612 }
2613 vfe_bus_local = *vfe_bus;
2614
2615 bus_priv = vfe_bus_local->bus_priv;
2616 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002617 CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002618 rc = -ENODEV;
2619 goto free_bus_local;
2620 }
2621
Harsh Shah19f55812017-06-26 18:58:49 -07002622 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2623 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2624 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002625
2626 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2627 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2628 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002629 CAM_ERR(CAM_ISP,
2630 "Error! Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002631 }
2632
2633 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2634 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2635 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002636 CAM_ERR(CAM_ISP,
2637 "Error! Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002638 }
2639
2640 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2641 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2642 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002643 CAM_ERR(CAM_ISP,
2644 "Error! Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002645 }
2646
2647 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2648 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2649 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2650
Harsh Shah19f55812017-06-26 18:58:49 -07002651 rc = cam_irq_controller_deinit(
2652 &bus_priv->common_data.bus_irq_controller);
2653 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002654 CAM_ERR(CAM_ISP,
2655 "Error! Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002656
Harsh Shah545df9a2017-06-16 16:43:17 -07002657 kfree(vfe_bus_local->bus_priv);
2658
2659free_bus_local:
2660 kfree(vfe_bus_local);
2661
2662 *vfe_bus = NULL;
2663
2664 return rc;
2665}
2666