blob: 4d98e2963defe26fbaafbd5d149f9a9c071293d2 [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;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530694 case CAM_FORMAT_PLAIN64:
695 return PACKER_FMT_PLAIN_64;
696 case CAM_FORMAT_MIPI_RAW_6:
697 case CAM_FORMAT_MIPI_RAW_8:
698 case CAM_FORMAT_MIPI_RAW_10:
699 case CAM_FORMAT_MIPI_RAW_12:
700 case CAM_FORMAT_MIPI_RAW_14:
701 case CAM_FORMAT_MIPI_RAW_16:
702 case CAM_FORMAT_MIPI_RAW_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530703 case CAM_FORMAT_PLAIN128:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530704 case CAM_FORMAT_PLAIN8:
705 case CAM_FORMAT_PLAIN16_8:
706 case CAM_FORMAT_PLAIN16_10:
707 case CAM_FORMAT_PLAIN16_12:
708 case CAM_FORMAT_PLAIN16_14:
709 case CAM_FORMAT_PLAIN16_16:
710 case CAM_FORMAT_PLAIN32_20:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530711 case CAM_FORMAT_PD8:
712 case CAM_FORMAT_PD10:
713 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700714 case CAM_FORMAT_UBWC_TP10:
715 case CAM_FORMAT_TP10:
716 return PACKER_FMT_TP_10;
Harsh Shaha1af8822017-05-11 22:06:36 -0700717 default:
718 return PACKER_FMT_MAX;
719 }
720}
721
722static int cam_vfe_bus_acquire_wm(
723 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
724 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700725 void *tasklet,
726 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700727 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
728 enum cam_vfe_bus_plane_type plane,
729 enum cam_isp_hw_split_id split_id,
730 uint32_t subscribe_irq,
731 struct cam_isp_resource_node **wm_res,
732 uint32_t *client_done_mask)
733{
734 uint32_t wm_idx = 0;
735 struct cam_isp_resource_node *wm_res_local = NULL;
736 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
737
738 *wm_res = NULL;
739 *client_done_mask = 0;
740
741 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
742 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
743 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700744 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700745 vfe_out_res_id, plane);
746 return -EINVAL;
747 }
748
749 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700750 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700751 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
752
753 rsrc_data = wm_res_local->res_priv;
754 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700755 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700756 rsrc_data->format = out_port_info->format;
757 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
758
759 rsrc_data->width = out_port_info->width;
760 rsrc_data->height = out_port_info->height;
Harsh Shahf7136392017-08-29 12:42:52 -0700761 CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index,
762 rsrc_data->width, rsrc_data->height);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700763
764 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700765 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Harsh Shahf7136392017-08-29 12:42:52 -0700766 switch (rsrc_data->format) {
767 case CAM_FORMAT_MIPI_RAW_6:
768 case CAM_FORMAT_MIPI_RAW_8:
769 case CAM_FORMAT_MIPI_RAW_10:
770 case CAM_FORMAT_MIPI_RAW_12:
771 case CAM_FORMAT_MIPI_RAW_14:
772 case CAM_FORMAT_MIPI_RAW_16:
773 case CAM_FORMAT_MIPI_RAW_20:
774 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
775 rsrc_data->height = 0;
776 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
777 rsrc_data->pack_fmt = 0x0;
778 rsrc_data->en_cfg = 0x3;
779 break;
780 case CAM_FORMAT_PLAIN8:
781 rsrc_data->en_cfg = 0x1;
782 rsrc_data->pack_fmt = 0x1;
783 rsrc_data->width = rsrc_data->width * 2;
784 rsrc_data->stride = rsrc_data->width;
785 break;
786 case CAM_FORMAT_PLAIN16_10:
787 rsrc_data->en_cfg = 0x1;
788 rsrc_data->pack_fmt = 0x2;
789 rsrc_data->width = rsrc_data->width * 2;
790 rsrc_data->stride = rsrc_data->width;
791 break;
792 case CAM_FORMAT_PLAIN16_12:
793 rsrc_data->en_cfg = 0x1;
794 rsrc_data->pack_fmt = 0x3;
795 rsrc_data->width = rsrc_data->width * 2;
796 rsrc_data->stride = rsrc_data->width;
797 break;
798 case CAM_FORMAT_PLAIN16_14:
799 rsrc_data->en_cfg = 0x1;
800 rsrc_data->pack_fmt = 0x4;
801 rsrc_data->width = rsrc_data->width * 2;
802 rsrc_data->stride = rsrc_data->width;
803 break;
804 case CAM_FORMAT_PLAIN16_16:
805 rsrc_data->en_cfg = 0x1;
806 rsrc_data->pack_fmt = 0x5;
807 rsrc_data->width = rsrc_data->width * 2;
808 rsrc_data->stride = rsrc_data->width;
809 break;
810 case CAM_FORMAT_PLAIN32_20:
811 rsrc_data->en_cfg = 0x1;
812 rsrc_data->pack_fmt = 0x9;
813 break;
814 case CAM_FORMAT_PLAIN64:
815 rsrc_data->en_cfg = 0x1;
816 rsrc_data->pack_fmt = 0xA;
817 break;
818 case CAM_FORMAT_PLAIN128:
819 rsrc_data->en_cfg = 0x1;
820 rsrc_data->pack_fmt = 0x0;
821 break;
822 default:
823 CAM_ERR(CAM_ISP, "Unsupported RDI format %d",
824 rsrc_data->format);
825 return -EINVAL;
826 }
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530827 } else if (rsrc_data->index < 5 ||
828 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700829 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
830 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700831 case CAM_FORMAT_UBWC_NV12_4R:
832 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700833 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
834 switch (plane) {
835 case PLANE_C:
836 rsrc_data->height /= 2;
837 break;
838 case PLANE_Y:
839 break;
840 default:
841 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
842 return -EINVAL;
843 }
844 break;
845 case CAM_FORMAT_UBWC_NV12:
846 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700847 /* Fall through for NV12 */
848 case CAM_FORMAT_NV21:
849 case CAM_FORMAT_NV12:
850 switch (plane) {
851 case PLANE_C:
852 rsrc_data->height /= 2;
853 break;
854 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700855 break;
856 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700857 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
858 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700859 }
860 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700861 case CAM_FORMAT_UBWC_TP10:
862 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700863 rsrc_data->width =
864 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
865 switch (plane) {
866 case PLANE_C:
867 rsrc_data->height /= 2;
868 break;
869 case PLANE_Y:
870 break;
871 default:
872 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
873 return -EINVAL;
874 }
875 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700876 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700877 rsrc_data->width =
878 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700879 switch (plane) {
880 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700881 rsrc_data->height /= 2;
882 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700883 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700884 break;
885 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700886 CAM_ERR(CAM_ISP, "Invalid plane %d\n", plane);
887 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700888 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700889 break;
890 default:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700891 CAM_ERR(CAM_ISP, "Invalid format %d\n",
892 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700893 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700894 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700895 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530896 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700897 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530898 rsrc_data->width = 0;
899 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530900 rsrc_data->stride = 1;
901 rsrc_data->en_cfg = 0x3;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700902 } else {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700903 /* Write master 5-6 DS ports , 9 - Raw dump , 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700904 rsrc_data->width = rsrc_data->width * 4;
905 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700906 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700907 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700908
909 *client_done_mask = (1 << wm_idx);
910 *wm_res = wm_res_local;
911
912 return 0;
913}
914
915static int cam_vfe_bus_release_wm(void *bus_priv,
916 struct cam_isp_resource_node *wm_res)
917{
918 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
919 wm_res->res_priv;
920
921 rsrc_data->irq_enabled = 0;
922 rsrc_data->offset = 0;
923 rsrc_data->width = 0;
924 rsrc_data->height = 0;
925 rsrc_data->stride = 0;
926 rsrc_data->format = 0;
927 rsrc_data->pack_fmt = 0;
928 rsrc_data->burst_len = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -0700929 rsrc_data->irq_subsample_period = 0;
930 rsrc_data->irq_subsample_pattern = 0;
931 rsrc_data->framedrop_period = 0;
932 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700933 rsrc_data->packer_cfg = 0;
934 rsrc_data->en_ubwc = 0;
935 rsrc_data->tile_cfg = 0;
936 rsrc_data->h_init = 0;
937 rsrc_data->v_init = 0;
938 rsrc_data->ubwc_meta_stride = 0;
939 rsrc_data->ubwc_mode_cfg = 0;
940 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700941 rsrc_data->init_cfg_done = false;
942 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700943 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700944
945 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700946 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
947
948 return 0;
949}
950
951static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
952{
953 int rc = 0;
954 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
955 wm_res->res_priv;
956 struct cam_vfe_bus_ver2_common_data *common_data =
957 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -0700958 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -0700959
Harsh Shah23557ae2017-05-13 18:14:34 -0700960 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
961 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -0700962 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
963
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700964 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -0700965 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700966 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -0700967 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700968 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -0700969 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -0700970
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530971 /* Configure stride for RDIs */
972 if (rsrc_data->index < 3)
973 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
974 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -0700975
Harsh Shah19f55812017-06-26 18:58:49 -0700976 /* Subscribe IRQ */
977 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700978 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -0700979 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
980 (1 << rsrc_data->index);
981 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
982 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
983 bus_irq_reg_mask, wm_res,
984 wm_res->top_half_handler,
985 cam_ife_mgr_do_tasklet_buf_done,
986 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
987 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700988 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -0700989 rsrc_data->index);
990 return -EFAULT;
991 }
992 }
993
Junzhe Zou3d292562017-07-12 17:59:58 -0700994 /* enable ubwc if needed*/
995 if (rsrc_data->en_ubwc) {
996 cam_io_w_mb(0x1, common_data->mem_base +
997 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
998 }
999
Harsh Shah19f55812017-06-26 18:58:49 -07001000 /* Enable WM */
1001 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
1002 rsrc_data->hw_regs->cfg);
1003
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001004 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001005 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001006 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001007 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001008 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001009 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001010 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
1011 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
1012 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001013
1014 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1015
1016 return rc;
1017}
1018
1019static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
1020{
1021 int rc = 0;
1022 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1023 wm_res->res_priv;
1024 struct cam_vfe_bus_ver2_common_data *common_data =
1025 rsrc_data->common_data;
1026
1027 /* Disble WM */
1028 cam_io_w_mb(0x0,
1029 common_data->mem_base + rsrc_data->hw_regs->cfg);
1030
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001031 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -07001032 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001033 if (rsrc_data->irq_enabled)
1034 rc = cam_irq_controller_unsubscribe_irq(
1035 common_data->bus_irq_controller,
1036 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001037
1038 /* Halt & Reset WM */
1039 cam_io_w_mb(BIT(rsrc_data->index),
1040 common_data->mem_base + common_data->common_reg->sw_reset);
1041
1042 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1043
1044 return rc;
1045}
1046
1047static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
1048 struct cam_irq_th_payload *th_payload)
1049{
Harsh Shah19f55812017-06-26 18:58:49 -07001050 int32_t rc;
1051 int i;
1052 struct cam_isp_resource_node *wm_res = NULL;
1053 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
1054 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1055
1056 wm_res = th_payload->handler_priv;
1057 if (!wm_res) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001058 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001059 return -ENODEV;
1060 }
1061
1062 rsrc_data = wm_res->res_priv;
1063
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001064 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1065 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001066
1067 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1068 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001069 CAM_ERR_RATE_LIMIT(CAM_ISP,
1070 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001071 return rc;
1072 }
1073
1074 cam_isp_hw_get_timestamp(&evt_payload->ts);
1075
1076 evt_payload->ctx = rsrc_data->ctx;
1077 evt_payload->core_index = rsrc_data->common_data->core_index;
1078 evt_payload->evt_id = evt_id;
1079
1080 for (i = 0; i < th_payload->num_registers; i++)
1081 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1082
1083 th_payload->evt_payload_priv = evt_payload;
1084
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001085 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001086 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001087}
1088
1089static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1090 void *evt_payload_priv)
1091{
1092 int rc = CAM_VFE_IRQ_STATUS_ERR;
1093 struct cam_isp_resource_node *wm_res = wm_node;
1094 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001095 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1096 (wm_res == NULL) ? NULL : wm_res->res_priv;
1097 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001098 uint32_t status_reg;
1099
Harsh Shah23557ae2017-05-13 18:14:34 -07001100 if (!evt_payload || !rsrc_data)
1101 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001102
Harsh Shah23557ae2017-05-13 18:14:34 -07001103 cam_ife_irq_regs = evt_payload->irq_reg_val;
1104 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1105
1106 if (status_reg & BIT(rsrc_data->index)) {
1107 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1108 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001109 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001110 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001111 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001112
1113 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001114 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001115 &evt_payload);
1116
1117 return rc;
1118}
1119
1120static int cam_vfe_bus_init_wm_resource(uint32_t index,
1121 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1122 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1123 struct cam_isp_resource_node *wm_res)
1124{
Harsh Shaha1af8822017-05-11 22:06:36 -07001125 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1126
1127 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1128 GFP_KERNEL);
1129 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001130 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001131 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001132 }
1133 wm_res->res_priv = rsrc_data;
1134
1135 rsrc_data->index = index;
1136 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1137 rsrc_data->common_data = &ver2_bus_priv->common_data;
1138
1139 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1140 INIT_LIST_HEAD(&wm_res->list);
1141
1142 wm_res->start = cam_vfe_bus_start_wm;
1143 wm_res->stop = cam_vfe_bus_stop_wm;
1144 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1145 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1146 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1147
Harsh Shah545df9a2017-06-16 16:43:17 -07001148 return 0;
1149}
1150
1151static int cam_vfe_bus_deinit_wm_resource(
1152 struct cam_isp_resource_node *wm_res)
1153{
1154 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1155
1156 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1157 INIT_LIST_HEAD(&wm_res->list);
1158
1159 wm_res->start = NULL;
1160 wm_res->stop = NULL;
1161 wm_res->top_half_handler = NULL;
1162 wm_res->bottom_half_handler = NULL;
1163 wm_res->hw_intf = NULL;
1164
1165 rsrc_data = wm_res->res_priv;
1166 wm_res->res_priv = NULL;
1167 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001168 CAM_ERR(CAM_ISP, "Error! WM res priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001169 return -ENOMEM;
1170 }
1171 kfree(rsrc_data);
1172
1173 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001174}
1175
1176static void cam_vfe_bus_add_wm_to_comp_grp(
1177 struct cam_isp_resource_node *comp_grp,
1178 uint32_t composite_mask)
1179{
1180 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1181
1182 rsrc_data->composite_mask |= composite_mask;
1183}
1184
1185static void cam_vfe_bus_match_comp_grp(
1186 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1187 struct cam_isp_resource_node **comp_grp,
1188 uint32_t comp_grp_local_idx,
1189 uint32_t unique_id)
1190{
1191 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1192 struct cam_isp_resource_node *comp_grp_local = NULL;
1193
1194 list_for_each_entry(comp_grp_local,
1195 &ver2_bus_priv->used_comp_grp, list) {
1196 rsrc_data = comp_grp_local->res_priv;
1197 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1198 rsrc_data->unique_id == unique_id) {
1199 /* Match found */
1200 *comp_grp = comp_grp_local;
1201 return;
1202 }
1203 }
1204
1205 *comp_grp = NULL;
1206}
1207
1208static int cam_vfe_bus_acquire_comp_grp(
1209 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1210 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001211 void *tasklet,
1212 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001213 uint32_t unique_id,
1214 uint32_t is_dual,
1215 uint32_t is_master,
1216 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1217 struct cam_isp_resource_node **comp_grp)
1218{
1219 int rc = 0;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001220 uint32_t bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001221 struct cam_isp_resource_node *comp_grp_local = NULL;
1222 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1223
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001224 bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
1225 out_port_info->comp_grp_id);
1226 /* Perform match only if there is valid comp grp request */
1227 if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
1228 /* Check if matching comp_grp already acquired */
1229 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1230 bus_comp_grp_id, unique_id);
1231 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001232
1233 if (!comp_grp_local) {
1234 /* First find a free group */
1235 if (is_dual) {
1236 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001237 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001238 return -ENODEV;
1239 }
1240 comp_grp_local = list_first_entry(
1241 &ver2_bus_priv->free_dual_comp_grp,
1242 struct cam_isp_resource_node, list);
1243 rsrc_data = comp_grp_local->res_priv;
1244 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1245 dual_slave_core,
1246 comp_grp_local->hw_intf->hw_idx,
1247 &rsrc_data->intra_client_mask);
1248 } else {
1249 if (list_empty(&ver2_bus_priv->free_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_comp_grp,
1255 struct cam_isp_resource_node, list);
1256 rsrc_data = comp_grp_local->res_priv;
1257 }
1258
1259 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001260 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001261 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1262
1263 rsrc_data->is_master = is_master;
1264 rsrc_data->composite_mask = 0;
1265 rsrc_data->unique_id = unique_id;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001266 rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001267
1268 list_add_tail(&comp_grp_local->list,
1269 &ver2_bus_priv->used_comp_grp);
1270
1271 } else {
1272 rsrc_data = comp_grp_local->res_priv;
1273 /* Do not support runtime change in composite mask */
1274 if (comp_grp_local->res_state ==
1275 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001276 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001277 comp_grp_local->res_state,
1278 rsrc_data->comp_grp_type);
1279 return -EBUSY;
1280 }
1281 }
1282
Harsh Shah19f55812017-06-26 18:58:49 -07001283 rsrc_data->ctx = ctx;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001284 rsrc_data->acquire_dev_cnt++;
Harsh Shaha1af8822017-05-11 22:06:36 -07001285 *comp_grp = comp_grp_local;
1286
1287 return rc;
1288}
1289
1290static int cam_vfe_bus_release_comp_grp(
1291 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1292 struct cam_isp_resource_node *in_comp_grp)
1293{
1294 struct cam_isp_resource_node *comp_grp = NULL;
1295 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1296 int match_found = 0;
1297
1298 if (!in_comp_grp) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001299 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
Harsh Shaha1af8822017-05-11 22:06:36 -07001300 return -EINVAL;
1301 }
1302
1303 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001304 CAM_ERR(CAM_ISP, "Already released Comp Grp");
Harsh Shaha1af8822017-05-11 22:06:36 -07001305 return 0;
1306 }
1307
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001308 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
1309 CAM_ERR(CAM_ISP, "Invalid State %d",
1310 in_comp_grp->res_state);
1311 return -EBUSY;
1312 }
1313
Harsh Shaha1af8822017-05-11 22:06:36 -07001314 in_rsrc_data = in_comp_grp->res_priv;
1315
1316 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1317 if (comp_grp == in_comp_grp) {
1318 match_found = 1;
1319 break;
1320 }
1321 }
1322
1323 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001324 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001325 in_rsrc_data->comp_grp_type);
1326 return -ENODEV;
1327 }
1328
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001329 in_rsrc_data->acquire_dev_cnt--;
1330 if (in_rsrc_data->acquire_dev_cnt == 0) {
1331 list_del(&comp_grp->list);
Harsh Shaha1af8822017-05-11 22:06:36 -07001332
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001333 in_rsrc_data->unique_id = 0;
1334 in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
1335 in_rsrc_data->composite_mask = 0;
1336 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
Harsh Shaha1af8822017-05-11 22:06:36 -07001337
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001338 comp_grp->tasklet_info = NULL;
1339 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
Harsh Shaha1af8822017-05-11 22:06:36 -07001340
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001341 if (in_rsrc_data->comp_grp_type >=
1342 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1343 in_rsrc_data->comp_grp_type <=
1344 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1345 list_add_tail(&comp_grp->list,
1346 &ver2_bus_priv->free_dual_comp_grp);
1347 else if (in_rsrc_data->comp_grp_type >=
1348 CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1349 in_rsrc_data->comp_grp_type <=
1350 CAM_VFE_BUS_VER2_COMP_GRP_5)
1351 list_add_tail(&comp_grp->list,
1352 &ver2_bus_priv->free_comp_grp);
1353 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001354
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001355 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001356}
1357
1358static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1359{
1360 int rc = 0;
1361 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1362 comp_grp->res_priv;
1363 struct cam_vfe_bus_ver2_common_data *common_data =
1364 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001365 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001366
1367 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1368 rsrc_data->hw_regs->comp_mask);
1369
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001370 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1371 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1372 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001373
1374 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1375 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1376 rsrc_data->is_master) {
1377 int dual_comp_grp = (rsrc_data->comp_grp_type -
1378 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1379 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1380 common_data->common_reg->dual_master_comp_cfg);
1381
1382 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1383 intra_client_en |=
1384 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1385
1386 cam_io_w_mb(intra_client_en, common_data->mem_base +
1387 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001388
1389 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1390 } else {
1391 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1392 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1393 (1 << (rsrc_data->comp_grp_type + 5));
1394 }
1395
1396 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001397 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001398 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1399 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1400 bus_irq_reg_mask, comp_grp,
1401 comp_grp->top_half_handler,
1402 cam_ife_mgr_do_tasklet_buf_done,
1403 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1404 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001405 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001406 rsrc_data->comp_grp_type);
1407 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001408 }
1409
1410 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001411
Harsh Shaha1af8822017-05-11 22:06:36 -07001412 return rc;
1413}
1414
1415static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1416{
1417 int rc = 0;
1418 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1419 comp_grp->res_priv;
1420 struct cam_vfe_bus_ver2_common_data *common_data =
1421 rsrc_data->common_data;
1422
1423 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001424 rc = cam_irq_controller_unsubscribe_irq(
1425 common_data->bus_irq_controller,
1426 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001427
1428 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1429 rsrc_data->hw_regs->comp_mask);
1430 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1431 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1432 rsrc_data->is_master) {
1433 int dual_comp_grp = (rsrc_data->comp_grp_type -
1434 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1435 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1436 common_data->common_reg->dual_master_comp_cfg);
1437
1438 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1439 intra_client_en &=
1440 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1441
1442 cam_io_w_mb(intra_client_en, common_data->mem_base +
1443 common_data->common_reg->dual_master_comp_cfg);
1444 }
1445
1446 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1447
1448 return rc;
1449}
1450
1451static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1452 struct cam_irq_th_payload *th_payload)
1453{
Harsh Shah19f55812017-06-26 18:58:49 -07001454 int32_t rc;
1455 int i;
1456 struct cam_isp_resource_node *comp_grp = NULL;
1457 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1458 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1459
1460 comp_grp = th_payload->handler_priv;
1461 if (!comp_grp) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001462 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! No resource\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001463 return -ENODEV;
1464 }
1465
1466 rsrc_data = comp_grp->res_priv;
1467
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001468 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1469 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001470
1471 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1472 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001473 CAM_ERR_RATE_LIMIT(CAM_ISP,
1474 "No tasklet_cmd is free in queue\n");
Harsh Shah19f55812017-06-26 18:58:49 -07001475 return rc;
1476 }
1477
1478 cam_isp_hw_get_timestamp(&evt_payload->ts);
1479
1480 evt_payload->ctx = rsrc_data->ctx;
1481 evt_payload->core_index = rsrc_data->common_data->core_index;
1482 evt_payload->evt_id = evt_id;
1483
1484 for (i = 0; i < th_payload->num_registers; i++)
1485 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1486
1487 th_payload->evt_payload_priv = evt_payload;
1488
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001489 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001490 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001491}
1492
1493static int cam_vfe_bus_handle_comp_done_bottom_half(
1494 void *handler_priv,
1495 void *evt_payload_priv)
1496{
1497 int rc = CAM_VFE_IRQ_STATUS_ERR;
1498 struct cam_isp_resource_node *comp_grp = handler_priv;
1499 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1500 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001501 uint32_t *cam_ife_irq_regs;
1502 uint32_t status_reg;
1503 uint32_t comp_err_reg;
1504 uint32_t comp_grp_id;
1505
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001506 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001507
Harsh Shah23557ae2017-05-13 18:14:34 -07001508 if (!evt_payload)
1509 return rc;
1510
1511 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001512
Harsh Shaha1af8822017-05-11 22:06:36 -07001513 switch (rsrc_data->comp_grp_type) {
1514 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1515 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1516 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1517 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1518 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1519 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001520 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001521 CAM_VFE_BUS_VER2_COMP_GRP_0);
1522
1523 /* Check for Regular composite error */
1524 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1525
1526 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1527 if ((status_reg & BIT(11)) &&
1528 (comp_err_reg & rsrc_data->composite_mask)) {
1529 /* Check for Regular composite error */
1530 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1531 break;
1532 }
1533
1534 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1535 /* Check for Regular composite Overwrite */
1536 if ((status_reg & BIT(12)) &&
1537 (comp_err_reg & rsrc_data->composite_mask)) {
1538 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1539 break;
1540 }
1541
Harsh Shah23557ae2017-05-13 18:14:34 -07001542 /* Regular Composite SUCCESS */
1543 if (status_reg & BIT(comp_grp_id + 5)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001544 rsrc_data->irq_trigger_cnt++;
1545 if (rsrc_data->irq_trigger_cnt ==
1546 rsrc_data->acquire_dev_cnt) {
1547 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1548 ~BIT(comp_grp_id + 5);
1549 rsrc_data->irq_trigger_cnt = 0;
1550 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001551 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001552 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001553
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001554 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001555 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001556 break;
1557
1558 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1559 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1560 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1561 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1562 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1563 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001564 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001565 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1566
1567 /* Check for DUAL composite error */
1568 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1569
1570 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1571 if ((status_reg & BIT(6)) &&
1572 (comp_err_reg & rsrc_data->composite_mask)) {
1573 /* Check for DUAL composite error */
1574 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1575 break;
1576 }
1577
1578 /* Check for Dual composite Overwrite */
1579 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1580 if ((status_reg & BIT(7)) &&
1581 (comp_err_reg & rsrc_data->composite_mask)) {
1582 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1583 break;
1584 }
1585
Harsh Shah23557ae2017-05-13 18:14:34 -07001586 /* DUAL Composite SUCCESS */
1587 if (status_reg & BIT(comp_grp_id)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001588 rsrc_data->irq_trigger_cnt++;
1589 if (rsrc_data->irq_trigger_cnt ==
1590 rsrc_data->acquire_dev_cnt) {
1591 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1592 ~BIT(comp_grp_id + 5);
1593 rsrc_data->irq_trigger_cnt = 0;
1594 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001595 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001596 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001597
1598 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001599 default:
1600 rc = CAM_VFE_IRQ_STATUS_ERR;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001601 CAM_ERR(CAM_ISP, "Error! Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001602 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001603 break;
1604 }
1605
1606 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001607 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001608 &evt_payload);
1609
1610 return rc;
1611}
1612
1613static int cam_vfe_bus_init_comp_grp(uint32_t index,
1614 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1615 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1616 struct cam_isp_resource_node *comp_grp)
1617{
Harsh Shah545df9a2017-06-16 16:43:17 -07001618 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001619
1620 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1621 GFP_KERNEL);
1622 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001623 CAM_DBG(CAM_ISP, "Failed to alloc for comp_grp_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001624 return -ENOMEM;
1625 }
1626 comp_grp->res_priv = rsrc_data;
1627
1628 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1629 INIT_LIST_HEAD(&comp_grp->list);
1630
1631 rsrc_data->comp_grp_type = index;
1632 rsrc_data->common_data = &ver2_bus_priv->common_data;
1633 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1634 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1635
Harsh Shaha1af8822017-05-11 22:06:36 -07001636 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1637 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1638 list_add_tail(&comp_grp->list,
1639 &ver2_bus_priv->free_dual_comp_grp);
1640 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1641 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1642 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1643
1644 comp_grp->start = cam_vfe_bus_start_comp_grp;
1645 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1646 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1647 comp_grp->bottom_half_handler =
1648 cam_vfe_bus_handle_comp_done_bottom_half;
1649 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1650
1651 return 0;
1652}
1653
Harsh Shah545df9a2017-06-16 16:43:17 -07001654static int cam_vfe_bus_deinit_comp_grp(
1655 struct cam_isp_resource_node *comp_grp)
1656{
1657 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1658 comp_grp->res_priv;
1659
1660 comp_grp->start = NULL;
1661 comp_grp->stop = NULL;
1662 comp_grp->top_half_handler = NULL;
1663 comp_grp->bottom_half_handler = NULL;
1664 comp_grp->hw_intf = NULL;
1665
1666 list_del_init(&comp_grp->list);
1667 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1668
1669 comp_grp->res_priv = NULL;
1670
1671 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001672 CAM_ERR(CAM_ISP, "Error! comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001673 return -ENODEV;
1674 }
1675 kfree(rsrc_data);
1676
1677 return 0;
1678}
1679
Harsh Shah19f55812017-06-26 18:58:49 -07001680static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1681 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001682{
1683 int rc = -ENODEV;
1684 int i;
1685 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1686 uint32_t format;
1687 uint32_t num_wm;
1688 uint32_t subscribe_irq;
1689 uint32_t client_done_mask;
1690 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1691 struct cam_vfe_acquire_args *acq_args = acquire_args;
1692 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1693 struct cam_isp_resource_node *rsrc_node = NULL;
1694 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1695
1696 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001697 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001698 return -EINVAL;
1699 }
1700
1701 out_acquire_args = &acq_args->vfe_out;
1702 format = out_acquire_args->out_port_info->format;
1703
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001704 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001705 out_acquire_args->out_port_info->res_type);
1706
1707 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1708 out_acquire_args->out_port_info->res_type);
1709 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1710 return -ENODEV;
1711
1712 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1713 if (num_wm < 1)
1714 return -EINVAL;
1715
1716 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1717 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001718 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001719 vfe_out_res_id, rsrc_node->res_state);
1720 return -EBUSY;
1721 }
1722
1723 rsrc_data = rsrc_node->res_priv;
1724 rsrc_data->num_wm = num_wm;
1725 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1726 rsrc_node->tasklet_info = acq_args->tasklet;
1727 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1728 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1729
1730 /* Reserve Composite Group */
1731 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1732 CAM_ISP_RES_COMP_GROUP_NONE &&
1733 out_acquire_args->out_port_info->comp_grp_id <
1734 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1735 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1736 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001737 acq_args->tasklet,
1738 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001739 out_acquire_args->unique_id,
1740 out_acquire_args->is_dual,
1741 out_acquire_args->is_master,
1742 out_acquire_args->dual_slave_core,
1743 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001744 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001745 CAM_ERR(CAM_ISP,
1746 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001747 rsrc_data->common_data->core_index,
1748 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001749 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001750 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001751
1752 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001753 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001754 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001755 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001756
1757 /* Reserve WM */
1758 for (i = 0; i < num_wm; i++) {
1759 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1760 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001761 acq_args->tasklet,
1762 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001763 vfe_out_res_id,
1764 i,
1765 out_acquire_args->split_id,
1766 subscribe_irq,
1767 &rsrc_data->wm_res[i],
1768 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001769 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001770 CAM_ERR(CAM_ISP,
1771 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001772 rsrc_data->common_data->core_index,
1773 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001774 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001775 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001776
1777 if (rsrc_data->comp_grp)
1778 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1779 client_done_mask);
1780 }
1781
1782 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1783 out_acquire_args->rsrc_node = rsrc_node;
1784
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001785 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001786 return rc;
1787
1788release_wm:
1789 for (i--; i >= 0; i--)
1790 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1791
1792 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1793 rsrc_data->comp_grp);
1794
1795 return rc;
1796}
1797
Harsh Shah19f55812017-06-26 18:58:49 -07001798static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1799 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001800{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001801 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001802 struct cam_isp_resource_node *vfe_out = NULL;
1803 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1804
1805 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001806 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001807 bus_priv, release_args);
1808 return -EINVAL;
1809 }
1810
1811 vfe_out = release_args;
1812 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001813
Harsh Shaha1af8822017-05-11 22:06:36 -07001814 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001815 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001816 vfe_out->res_state);
1817 }
1818
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001819 for (i = 0; i < rsrc_data->num_wm; i++)
1820 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1821 rsrc_data->num_wm = 0;
1822
1823 if (rsrc_data->comp_grp)
1824 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1825 rsrc_data->comp_grp = NULL;
1826
1827 vfe_out->tasklet_info = NULL;
1828 vfe_out->cdm_ops = NULL;
1829 rsrc_data->cdm_util_ops = NULL;
1830
Harsh Shaha1af8822017-05-11 22:06:36 -07001831 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1832 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1833
1834 return 0;
1835}
1836
Harsh Shah19f55812017-06-26 18:58:49 -07001837static int cam_vfe_bus_start_vfe_out(
1838 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001839{
1840 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001841 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1842 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1843
1844 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001845 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001846 return -EINVAL;
1847 }
1848
1849 rsrc_data = vfe_out->res_priv;
1850 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001851
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001852 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001853
1854 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001855 CAM_ERR(CAM_ISP, "Error! Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001856 vfe_out->res_state);
1857 return -EACCES;
1858 }
1859
1860 for (i = 0; i < rsrc_data->num_wm; i++)
1861 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1862
1863 if (rsrc_data->comp_grp)
1864 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1865
Harsh Shaha1af8822017-05-11 22:06:36 -07001866 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1867 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1868 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1869 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1870 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1871 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001872 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1873 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1874 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1875 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1876 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1877 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1878 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1879 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1880 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1881
Harsh Shah23557ae2017-05-13 18:14:34 -07001882 /* no clock gating at bus input */
1883 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1884
1885 /* BUS_WR_TEST_BUS_CTRL */
1886 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
1887
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05301888 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07001889 return rc;
1890}
1891
Harsh Shah19f55812017-06-26 18:58:49 -07001892static int cam_vfe_bus_stop_vfe_out(
1893 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001894{
1895 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001896 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1897
1898 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001899 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001900 return -EINVAL;
1901 }
1902
1903 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07001904
1905 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
1906 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
1907 return rc;
1908 }
1909
1910 if (rsrc_data->comp_grp)
1911 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
1912
1913 for (i = 0; i < rsrc_data->num_wm; i++)
1914 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
1915
Harsh Shaha1af8822017-05-11 22:06:36 -07001916
1917 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1918 return rc;
1919}
1920
1921static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
1922 struct cam_irq_th_payload *th_payload)
1923{
1924 return -EPERM;
1925}
1926
1927static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
1928 void *handler_priv,
1929 void *evt_payload_priv)
1930{
1931 int rc = -EINVAL;
1932 struct cam_isp_resource_node *vfe_out = handler_priv;
1933 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1934
1935 /*
1936 * If this resource has Composite Group then we only handle
1937 * Composite done. We acquire Composite if number of WM > 1.
1938 * So Else case is only one individual buf_done = WM[0].
1939 */
1940 if (rsrc_data->comp_grp) {
1941 rc = rsrc_data->comp_grp->bottom_half_handler(
1942 rsrc_data->comp_grp, evt_payload_priv);
1943 } else {
1944 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07001945 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07001946 }
1947
1948 return rc;
1949}
1950
1951static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
1952 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1953 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1954 struct cam_isp_resource_node *vfe_out)
1955{
1956 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1957 int rc = 0;
1958
1959 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
1960 GFP_KERNEL);
1961 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001962 CAM_DBG(CAM_ISP, "Error! Failed to alloc for vfe out priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07001963 rc = -ENOMEM;
1964 return rc;
1965 }
1966 vfe_out->res_priv = rsrc_data;
1967
1968 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
1969 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1970 INIT_LIST_HEAD(&vfe_out->list);
1971
1972 rsrc_data->out_type = index;
1973 rsrc_data->common_data = &ver2_bus_priv->common_data;
1974 rsrc_data->max_width =
1975 ver2_hw_info->vfe_out_hw_info[index].max_width;
1976 rsrc_data->max_height =
1977 ver2_hw_info->vfe_out_hw_info[index].max_height;
1978
1979 vfe_out->start = cam_vfe_bus_start_vfe_out;
1980 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
1981 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
1982 vfe_out->bottom_half_handler =
1983 cam_vfe_bus_handle_vfe_out_done_bottom_half;
1984 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
1985
1986 return 0;
1987}
1988
Harsh Shah545df9a2017-06-16 16:43:17 -07001989static int cam_vfe_bus_deinit_vfe_out_resource(
1990 struct cam_isp_resource_node *vfe_out)
1991{
1992 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
1993
1994 vfe_out->start = NULL;
1995 vfe_out->stop = NULL;
1996 vfe_out->top_half_handler = NULL;
1997 vfe_out->bottom_half_handler = NULL;
1998 vfe_out->hw_intf = NULL;
1999
2000 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
2001 INIT_LIST_HEAD(&vfe_out->list);
2002 vfe_out->res_priv = NULL;
2003
2004 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002005 CAM_ERR(CAM_ISP, "Error! vfe out priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002006 return -ENOMEM;
2007 }
2008 kfree(rsrc_data);
2009
2010 return 0;
2011}
2012
Harsh Shaha1af8822017-05-11 22:06:36 -07002013static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
2014 struct cam_irq_th_payload *th_payload)
2015{
Harsh Shaha1af8822017-05-11 22:06:36 -07002016 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002017
Harsh Shah19f55812017-06-26 18:58:49 -07002018 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002019 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07002020 return cam_irq_controller_handle_irq(evt_id,
2021 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07002022}
2023
2024static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
2025 uint32_t arg_size)
2026{
2027 struct cam_vfe_bus_ver2_priv *bus_priv;
2028 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002029 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07002030 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2031 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002032 uint32_t *reg_val_pair;
2033 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07002034 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07002035
2036 /*
2037 * Need the entire buf io config so we can get the stride info
2038 * for the wm.
2039 */
2040
2041 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2042 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
2043
2044 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2045 update_buf->cdm.res->res_priv;
2046
2047 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002048 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07002049 return -EINVAL;
2050 }
2051
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002052 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002053 CAM_ERR(CAM_ISP,
2054 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002055 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07002056 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07002057 }
2058
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002059 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2060 io_cfg = update_buf->io_cfg;
2061
2062 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07002063 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002064 CAM_ERR(CAM_ISP,
2065 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07002066 j, MAX_REG_VAL_PAIR_SIZE);
2067 return -ENOMEM;
2068 }
2069
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002070 wm_data = vfe_out_data->wm_res[i]->res_priv;
2071
2072 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302073 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
2074 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002075 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2076 wm_data->hw_regs->stride,
2077 io_cfg->planes[i].plane_stride);
2078 wm_data->stride = io_cfg->planes[i].plane_stride;
2079 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002080 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002081
2082 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002083 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002084 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2085 wm_data->hw_regs->framedrop_pattern,
2086 io_cfg->framedrop_pattern);
2087 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
2088 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002089 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2090 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002091
2092 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002093 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002094 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2095 wm_data->hw_regs->framedrop_period,
2096 io_cfg->framedrop_period);
2097 wm_data->framedrop_period = io_cfg->framedrop_period;
2098 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002099 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2100 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002101
2102 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002103 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002104 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2105 wm_data->hw_regs->irq_subsample_period,
2106 io_cfg->subsample_period);
2107 wm_data->irq_subsample_period =
2108 io_cfg->subsample_period;
2109 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002110 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002111 wm_data->irq_subsample_period);
2112
2113 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002114 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002115 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2116 wm_data->hw_regs->irq_subsample_pattern,
2117 io_cfg->subsample_pattern);
2118 wm_data->irq_subsample_pattern =
2119 io_cfg->subsample_pattern;
2120 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002121 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002122 wm_data->irq_subsample_pattern);
2123
2124 if (wm_data->en_ubwc) {
2125 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002126 CAM_ERR(CAM_ISP,
2127 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002128 return -EINVAL;
2129 }
2130 if (wm_data->packer_cfg !=
2131 io_cfg->planes[i].packer_config ||
2132 !wm_data->init_cfg_done) {
2133 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2134 wm_data->hw_regs->packer_cfg,
2135 io_cfg->planes[i].packer_config);
2136 wm_data->packer_cfg =
2137 io_cfg->planes[i].packer_config;
2138 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002139 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2140 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002141
2142 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
2143 || !wm_data->init_cfg_done) {
2144 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2145 wm_data->hw_regs->ubwc_regs->tile_cfg,
2146 io_cfg->planes[i].tile_config);
2147 wm_data->tile_cfg =
2148 io_cfg->planes[i].tile_config;
2149 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002150 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002151
2152 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2153 !wm_data->init_cfg_done) {
2154 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2155 wm_data->hw_regs->ubwc_regs->h_init,
2156 io_cfg->planes[i].h_init);
2157 wm_data->h_init = io_cfg->planes[i].h_init;
2158 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002159 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002160
2161 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2162 !wm_data->init_cfg_done) {
2163 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2164 wm_data->hw_regs->ubwc_regs->v_init,
2165 io_cfg->planes[i].v_init);
2166 wm_data->v_init = io_cfg->planes[i].v_init;
2167 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002168 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002169
2170 if (wm_data->ubwc_meta_stride !=
2171 io_cfg->planes[i].meta_stride ||
2172 !wm_data->init_cfg_done) {
2173 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2174 wm_data->hw_regs->ubwc_regs->
2175 meta_stride,
2176 io_cfg->planes[i].meta_stride);
2177 wm_data->ubwc_meta_stride =
2178 io_cfg->planes[i].meta_stride;
2179 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002180 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2181 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002182
2183 if (wm_data->ubwc_mode_cfg !=
2184 io_cfg->planes[i].mode_config ||
2185 !wm_data->init_cfg_done) {
2186 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2187 wm_data->hw_regs->ubwc_regs->mode_cfg,
2188 io_cfg->planes[i].mode_config);
2189 wm_data->ubwc_mode_cfg =
2190 io_cfg->planes[i].mode_config;
2191 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002192 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2193 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002194
2195 if (wm_data->ubwc_meta_offset !=
2196 io_cfg->planes[i].meta_offset ||
2197 !wm_data->init_cfg_done) {
2198 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2199 wm_data->hw_regs->ubwc_regs->
2200 meta_offset,
2201 io_cfg->planes[i].meta_offset);
2202 wm_data->ubwc_meta_offset =
2203 io_cfg->planes[i].meta_offset;
2204 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002205 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002206 wm_data->ubwc_meta_offset);
2207
2208 /* UBWC meta address */
2209 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2210 wm_data->hw_regs->ubwc_regs->meta_addr,
2211 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002212 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002213 update_buf->image_buf[i]);
2214 }
2215
2216 /* WM Image address */
2217 if (wm_data->en_ubwc)
2218 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2219 wm_data->hw_regs->image_addr,
2220 (update_buf->image_buf[i] +
2221 io_cfg->planes[i].meta_size));
2222 else
2223 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2224 wm_data->hw_regs->image_addr,
2225 update_buf->image_buf[i]);
2226
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002227 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002228
Junzhe Zou193d78c2017-05-16 15:10:54 -07002229 frame_inc = io_cfg->planes[i].plane_stride *
2230 io_cfg->planes[i].slice_height;
2231 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2232 wm_data->hw_regs->frame_inc, frame_inc);
2233
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002234 /* enable the WM */
2235 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2236 wm_data->hw_regs->cfg,
2237 wm_data->en_cfg);
2238
2239 /* set initial configuration done */
2240 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002241 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002242 }
2243
2244 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002245
2246 /* cdm util returns dwords, need to convert to bytes */
2247 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002248 CAM_ERR(CAM_ISP,
2249 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002250 update_buf->cdm.size, size);
2251 return -ENOMEM;
2252 }
2253
Harsh Shaha1af8822017-05-11 22:06:36 -07002254 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002255 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2256
Harsh Shaha1af8822017-05-11 22:06:36 -07002257 /* cdm util returns dwords, need to convert to bytes */
2258 update_buf->cdm.used_bytes = size * 4;
2259
2260 return 0;
2261}
2262
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002263static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2264 uint32_t arg_size)
2265{
2266 struct cam_vfe_bus_ver2_priv *bus_priv;
2267 struct cam_isp_hw_get_hfr_update *update_hfr;
2268 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2269 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2270 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2271 uint32_t *reg_val_pair;
2272 uint32_t i, j, size = 0;
2273
2274 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2275 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2276
2277 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2278 update_hfr->cdm.res->res_priv;
2279
2280 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2281 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2282 return -EINVAL;
2283 }
2284
2285 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2286 hfr_cfg = update_hfr->io_hfr_cfg;
2287
2288 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2289 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2290 CAM_ERR(CAM_ISP,
2291 "reg_val_pair %d exceeds the array limit %lu",
2292 j, MAX_REG_VAL_PAIR_SIZE);
2293 return -ENOMEM;
2294 }
2295
2296 wm_data = vfe_out_data->wm_res[i]->res_priv;
2297
2298 if ((wm_data->framedrop_pattern !=
2299 hfr_cfg->framedrop_pattern) ||
2300 !wm_data->hfr_cfg_done) {
2301 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2302 wm_data->hw_regs->framedrop_pattern,
2303 hfr_cfg->framedrop_pattern);
2304 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2305 }
2306 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2307 wm_data->framedrop_pattern);
2308
2309 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2310 !wm_data->hfr_cfg_done) {
2311 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2312 wm_data->hw_regs->framedrop_period,
2313 hfr_cfg->framedrop_period);
2314 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2315 }
2316 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2317 wm_data->framedrop_period);
2318
2319 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2320 || !wm_data->hfr_cfg_done) {
2321 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2322 wm_data->hw_regs->irq_subsample_period,
2323 hfr_cfg->subsample_period);
2324 wm_data->irq_subsample_period =
2325 hfr_cfg->subsample_period;
2326 }
2327 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2328 wm_data->irq_subsample_period);
2329
2330 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2331 || !wm_data->hfr_cfg_done) {
2332 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2333 wm_data->hw_regs->irq_subsample_pattern,
2334 hfr_cfg->subsample_pattern);
2335 wm_data->irq_subsample_pattern =
2336 hfr_cfg->subsample_pattern;
2337 }
2338 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2339 wm_data->irq_subsample_pattern);
2340
2341 /* set initial configuration done */
2342 if (!wm_data->hfr_cfg_done)
2343 wm_data->hfr_cfg_done = true;
2344 }
2345
2346 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2347
2348 /* cdm util returns dwords, need to convert to bytes */
2349 if ((size * 4) > update_hfr->cdm.size) {
2350 CAM_ERR(CAM_ISP,
2351 "Failed! Buf size:%d insufficient, expected size:%d",
2352 update_hfr->cdm.size, size);
2353 return -ENOMEM;
2354 }
2355
2356 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2357 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2358
2359 /* cdm util returns dwords, need to convert to bytes */
2360 update_hfr->cdm.used_bytes = size * 4;
2361
2362 return 0;
2363}
2364
Harsh Shah19f55812017-06-26 18:58:49 -07002365static int cam_vfe_bus_start_hw(void *hw_priv,
2366 void *start_hw_args, uint32_t arg_size)
2367{
2368 return cam_vfe_bus_start_vfe_out(hw_priv);
2369}
2370
2371static int cam_vfe_bus_stop_hw(void *hw_priv,
2372 void *stop_hw_args, uint32_t arg_size)
2373{
2374 return cam_vfe_bus_stop_vfe_out(hw_priv);
2375}
2376
2377static int cam_vfe_bus_init_hw(void *hw_priv,
2378 void *init_hw_args, uint32_t arg_size)
2379{
2380 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2381 uint32_t top_irq_reg_mask[2] = {0};
2382
2383 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002384 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002385 return -EINVAL;
2386 }
2387
2388 top_irq_reg_mask[0] = (1 << 9);
2389
2390 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2391 bus_priv->common_data.vfe_irq_controller,
2392 CAM_IRQ_PRIORITY_2,
2393 top_irq_reg_mask,
2394 bus_priv,
2395 cam_vfe_bus_ver2_handle_irq,
2396 NULL,
2397 NULL,
2398 NULL);
2399
2400 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002401 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002402 return -EFAULT;
2403 }
2404
2405 return 0;
2406}
2407
2408static int cam_vfe_bus_deinit_hw(void *hw_priv,
2409 void *deinit_hw_args, uint32_t arg_size)
2410{
2411 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2412 int rc;
2413
2414 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002415 CAM_ERR(CAM_ISP, "Error! Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002416 return -EINVAL;
2417 }
2418
2419 rc = cam_irq_controller_unsubscribe_irq(
2420 bus_priv->common_data.vfe_irq_controller,
2421 bus_priv->irq_handle);
2422 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002423 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002424
2425 return rc;
2426}
2427
Harsh Shaha1af8822017-05-11 22:06:36 -07002428static int cam_vfe_bus_process_cmd(void *priv,
2429 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2430{
2431 int rc = -EINVAL;
2432
2433 if (!priv || !cmd_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002434 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error! Invalid input arguments\n");
Harsh Shaha1af8822017-05-11 22:06:36 -07002435 return -EINVAL;
2436 }
2437
2438 switch (cmd_type) {
2439 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2440 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2441 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002442 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2443 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2444 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002445 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002446 CAM_ERR_RATE_LIMIT(CAM_ISP, "Inval camif process command:%d\n",
Harsh Shaha1af8822017-05-11 22:06:36 -07002447 cmd_type);
2448 break;
2449 }
2450
2451 return rc;
2452}
2453
2454int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002455 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002456 struct cam_hw_intf *hw_intf,
2457 void *bus_hw_info,
2458 void *vfe_irq_controller,
2459 struct cam_vfe_bus **vfe_bus)
2460{
2461 int i, rc = 0;
2462 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2463 struct cam_vfe_bus *vfe_bus_local;
2464 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2465
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002466 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002467
Harsh Shah19f55812017-06-26 18:58:49 -07002468 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002469 CAM_ERR(CAM_ISP,
2470 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2471 soc_info, hw_intf, bus_hw_info);
2472 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002473 rc = -EINVAL;
2474 goto end;
2475 }
2476
Harsh Shaha1af8822017-05-11 22:06:36 -07002477 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2478 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002479 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002480 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002481 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002482 }
2483
2484 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2485 GFP_KERNEL);
2486 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002487 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002488 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002489 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002490 }
2491 vfe_bus_local->bus_priv = bus_priv;
2492
Harsh Shah19f55812017-06-26 18:58:49 -07002493 bus_priv->common_data.core_index = soc_info->index;
2494 bus_priv->common_data.mem_base =
2495 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002496 bus_priv->common_data.hw_intf = hw_intf;
2497 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2498 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
2499
Harsh Shah19f55812017-06-26 18:58:49 -07002500 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2501 &ver2_hw_info->common_reg.irq_reg_info,
2502 &bus_priv->common_data.bus_irq_controller);
2503 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002504 CAM_ERR(CAM_ISP, "Error! cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002505 goto free_bus_priv;
2506 }
2507
Harsh Shaha1af8822017-05-11 22:06:36 -07002508 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2509 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2510 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2511
2512 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2513 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2514 &bus_priv->bus_client[i]);
2515 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002516 CAM_ERR(CAM_ISP, "Error! Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002517 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002518 }
2519 }
2520
2521 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2522 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2523 &bus_priv->comp_grp[i]);
2524 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002525 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002526 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002527 }
2528 }
2529
2530 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2531 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2532 &bus_priv->vfe_out[i]);
2533 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002534 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002535 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002536 }
2537 }
2538
Harsh Shah19f55812017-06-26 18:58:49 -07002539 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2540 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2541 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2542 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2543 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002544 }
2545
Harsh Shah19f55812017-06-26 18:58:49 -07002546 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2547 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2548 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2549 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2550 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2551 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2552 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002553 vfe_bus_local->bottom_half_handler = NULL;
Harsh Shah19f55812017-06-26 18:58:49 -07002554 vfe_bus_local->hw_ops.process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002555
2556 *vfe_bus = vfe_bus_local;
2557
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002558 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002559 return rc;
2560
Harsh Shah545df9a2017-06-16 16:43:17 -07002561deinit_vfe_out:
2562 if (i < 0)
2563 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2564 for (--i; i >= 0; i--)
2565 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2566
2567deinit_comp_grp:
2568 if (i < 0)
2569 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2570 for (--i; i >= 0; i--)
2571 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2572
2573deinit_wm:
2574 if (i < 0)
2575 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2576 for (--i; i >= 0; i--)
2577 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2578
Harsh Shah19f55812017-06-26 18:58:49 -07002579free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002580 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002581
2582free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002583 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002584
2585end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002586 return rc;
2587}
Harsh Shah545df9a2017-06-16 16:43:17 -07002588
2589int cam_vfe_bus_ver2_deinit(
2590 struct cam_vfe_bus **vfe_bus)
2591{
2592 int i, rc = 0;
2593 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2594 struct cam_vfe_bus *vfe_bus_local;
2595
2596 if (!vfe_bus || !*vfe_bus) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002597 CAM_ERR(CAM_ISP, "Error! Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002598 return -EINVAL;
2599 }
2600 vfe_bus_local = *vfe_bus;
2601
2602 bus_priv = vfe_bus_local->bus_priv;
2603 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002604 CAM_ERR(CAM_ISP, "Error! bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002605 rc = -ENODEV;
2606 goto free_bus_local;
2607 }
2608
Harsh Shah19f55812017-06-26 18:58:49 -07002609 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2610 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2611 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002612
2613 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2614 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2615 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002616 CAM_ERR(CAM_ISP,
2617 "Error! Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002618 }
2619
2620 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2621 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2622 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002623 CAM_ERR(CAM_ISP,
2624 "Error! Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002625 }
2626
2627 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2628 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2629 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002630 CAM_ERR(CAM_ISP,
2631 "Error! Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002632 }
2633
2634 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2635 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2636 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2637
Harsh Shah19f55812017-06-26 18:58:49 -07002638 rc = cam_irq_controller_deinit(
2639 &bus_priv->common_data.bus_irq_controller);
2640 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002641 CAM_ERR(CAM_ISP,
2642 "Error! Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002643
Harsh Shah545df9a2017-06-16 16:43:17 -07002644 kfree(vfe_bus_local->bus_priv);
2645
2646free_bus_local:
2647 kfree(vfe_bus_local);
2648
2649 *vfe_bus = NULL;
2650
2651 return rc;
2652}
2653