blob: 005d7e085c690c8226286d1d98b55e0ae16b4647 [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>
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +053015#include <uapi/media/cam_isp.h>
Harsh Shaha1af8822017-05-11 22:06:36 -070016#include "cam_io_util.h"
Harsh Shahf7136392017-08-29 12:42:52 -070017#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070018#include "cam_cdm_util.h"
19#include "cam_hw_intf.h"
Harsh Shah19f55812017-06-26 18:58:49 -070020#include "cam_ife_hw_mgr.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070021#include "cam_vfe_hw_intf.h"
22#include "cam_irq_controller.h"
Harsh Shah19f55812017-06-26 18:58:49 -070023#include "cam_tasklet_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070024#include "cam_vfe_bus.h"
25#include "cam_vfe_bus_ver2.h"
26#include "cam_vfe_core.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070027#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070028
Harsh Shah19f55812017-06-26 18:58:49 -070029static const char drv_name[] = "vfe_bus";
30
31#define CAM_VFE_BUS_IRQ_REG0 0
32#define CAM_VFE_BUS_IRQ_REG1 1
33#define CAM_VFE_BUS_IRQ_REG2 2
34#define CAM_VFE_BUS_IRQ_MAX 3
35
36#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
Harsh Shah23557ae2017-05-13 18:14:34 -070037
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +053038#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
39#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
40#define CAM_VFE_BUS_INTRA_CLIENT_MASK 0x3
41#define CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT 8
42#define CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL 0xFFFFF
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +053043
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -070044#define ALIGNUP(value, alignment) \
45 ((value + alignment - 1) / alignment * alignment)
46
Junzhe Zou193d78c2017-05-16 15:10:54 -070047#define MAX_BUF_UPDATE_REG_NUM \
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +053048 ((sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client) + \
49 sizeof(struct cam_vfe_bus_ver2_reg_offset_ubwc_client))/4)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070050#define MAX_REG_VAL_PAIR_SIZE \
Harsh Shah19f55812017-06-26 18:58:49 -070051 (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070052
53#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
Harsh Shah19f55812017-06-26 18:58:49 -070054 do { \
55 buf_array[index++] = offset; \
56 buf_array[index++] = val; \
57 } while (0)
Harsh Shaha1af8822017-05-11 22:06:36 -070058
59enum cam_vfe_bus_packer_format {
60 PACKER_FMT_PLAIN_128 = 0x0,
61 PACKER_FMT_PLAIN_8 = 0x1,
62 PACKER_FMT_PLAIN_16_10BPP = 0x2,
63 PACKER_FMT_PLAIN_16_12BPP = 0x3,
64 PACKER_FMT_PLAIN_16_14BPP = 0x4,
65 PACKER_FMT_PLAIN_16_16BPP = 0x5,
66 PACKER_FMT_ARGB_10 = 0x6,
67 PACKER_FMT_ARGB_12 = 0x7,
68 PACKER_FMT_ARGB_14 = 0x8,
69 PACKER_FMT_PLAIN_32_20BPP = 0x9,
70 PACKER_FMT_PLAIN_64 = 0xA,
71 PACKER_FMT_TP_10 = 0xB,
72 PACKER_FMT_PLAIN_32_32BPP = 0xC,
73 PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
74 PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
75 PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
76 PACKER_FMT_MAX = 0xF,
77};
78
Karthik Anantha Ram01974172017-09-01 10:42:22 -070079enum cam_vfe_bus_comp_grp_id {
80 CAM_VFE_BUS_COMP_GROUP_NONE = -EINVAL,
81 CAM_VFE_BUS_COMP_GROUP_ID_0 = 0x0,
82 CAM_VFE_BUS_COMP_GROUP_ID_1 = 0x1,
83 CAM_VFE_BUS_COMP_GROUP_ID_2 = 0x2,
84 CAM_VFE_BUS_COMP_GROUP_ID_3 = 0x3,
85 CAM_VFE_BUS_COMP_GROUP_ID_4 = 0x4,
86 CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5,
87};
88
Harsh Shaha1af8822017-05-11 22:06:36 -070089struct cam_vfe_bus_ver2_common_data {
Harsh Shah19f55812017-06-26 18:58:49 -070090 uint32_t core_index;
Harsh Shaha1af8822017-05-11 22:06:36 -070091 void __iomem *mem_base;
92 struct cam_hw_intf *hw_intf;
93 void *bus_irq_controller;
94 void *vfe_irq_controller;
95 struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070096 uint32_t io_buf_update[
Harsh Shah19f55812017-06-26 18:58:49 -070097 MAX_REG_VAL_PAIR_SIZE];
98
99 struct cam_vfe_bus_irq_evt_payload evt_payload[
100 CAM_VFE_BUS_VER2_PAYLOAD_MAX];
101 struct list_head free_payload_list;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700102 struct mutex bus_mutex;
103 uint32_t secure_mode;
104 uint32_t num_sec_out;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530105 uint32_t addr_no_sync;
Harsh Shaha1af8822017-05-11 22:06:36 -0700106};
107
108struct cam_vfe_bus_ver2_wm_resource_data {
109 uint32_t index;
110 struct cam_vfe_bus_ver2_common_data *common_data;
111 struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
Harsh Shah19f55812017-06-26 18:58:49 -0700112 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700113
114 uint32_t irq_enabled;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700115 bool init_cfg_done;
116 bool hfr_cfg_done;
Harsh Shah19f55812017-06-26 18:58:49 -0700117
Harsh Shaha1af8822017-05-11 22:06:36 -0700118 uint32_t offset;
119 uint32_t width;
120 uint32_t height;
121 uint32_t stride;
122 uint32_t format;
123 enum cam_vfe_bus_packer_format pack_fmt;
124
125 uint32_t burst_len;
Harsh Shaha1af8822017-05-11 22:06:36 -0700126
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700127 uint32_t en_ubwc;
128 uint32_t packer_cfg;
129 uint32_t tile_cfg;
130 uint32_t h_init;
131 uint32_t v_init;
132 uint32_t ubwc_meta_stride;
133 uint32_t ubwc_mode_cfg;
134 uint32_t ubwc_meta_offset;
135
Harsh Shaha1af8822017-05-11 22:06:36 -0700136 uint32_t irq_subsample_period;
137 uint32_t irq_subsample_pattern;
138 uint32_t framedrop_period;
139 uint32_t framedrop_pattern;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700140
141 uint32_t en_cfg;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530142 uint32_t is_dual;
Harsh Shaha1af8822017-05-11 22:06:36 -0700143};
144
145struct cam_vfe_bus_ver2_comp_grp_data {
146 enum cam_vfe_bus_ver2_comp_grp_type comp_grp_type;
147 struct cam_vfe_bus_ver2_common_data *common_data;
148 struct cam_vfe_bus_ver2_reg_offset_comp_grp *hw_regs;
149
150 uint32_t irq_enabled;
151 uint32_t comp_grp_local_idx;
152 uint32_t unique_id;
153
154 uint32_t is_master;
155 uint32_t dual_slave_core;
156 uint32_t intra_client_mask;
157 uint32_t composite_mask;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530158 uint32_t addr_sync_mode;
Harsh Shah19f55812017-06-26 18:58:49 -0700159
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700160 uint32_t acquire_dev_cnt;
161 uint32_t irq_trigger_cnt;
162
Harsh Shah19f55812017-06-26 18:58:49 -0700163 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700164};
165
166struct cam_vfe_bus_ver2_vfe_out_data {
167 uint32_t out_type;
168 struct cam_vfe_bus_ver2_common_data *common_data;
169
170 uint32_t num_wm;
171 struct cam_isp_resource_node *wm_res[PLANE_MAX];
172
173 struct cam_isp_resource_node *comp_grp;
174 enum cam_isp_hw_sync_mode dual_comp_sync_mode;
175 uint32_t dual_hw_alternate_vfe_id;
176 struct list_head vfe_out_list;
177
178 uint32_t format;
179 uint32_t max_width;
180 uint32_t max_height;
181 struct cam_cdm_utils_ops *cdm_util_ops;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700182 uint32_t secure_mode;
Harsh Shaha1af8822017-05-11 22:06:36 -0700183};
184
Harsh Shaha1af8822017-05-11 22:06:36 -0700185struct cam_vfe_bus_ver2_priv {
186 struct cam_vfe_bus_ver2_common_data common_data;
187
188 struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
189 struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
190 struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
191
192 struct list_head free_comp_grp;
193 struct list_head free_dual_comp_grp;
194 struct list_head used_comp_grp;
195
Harsh Shah19f55812017-06-26 18:58:49 -0700196 uint32_t irq_handle;
Harsh Shaha1af8822017-05-11 22:06:36 -0700197};
198
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700199static int cam_vfe_bus_process_cmd(
200 struct cam_isp_resource_node *priv,
201 uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
202
Harsh Shah19f55812017-06-26 18:58:49 -0700203static int cam_vfe_bus_get_evt_payload(
204 struct cam_vfe_bus_ver2_common_data *common_data,
205 struct cam_vfe_bus_irq_evt_payload **evt_payload)
206{
207 if (list_empty(&common_data->free_payload_list)) {
208 *evt_payload = NULL;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700209 CAM_ERR(CAM_ISP, "No free payload");
Harsh Shah19f55812017-06-26 18:58:49 -0700210 return -ENODEV;
211 }
212
213 *evt_payload = list_first_entry(&common_data->free_payload_list,
214 struct cam_vfe_bus_irq_evt_payload, list);
215 list_del_init(&(*evt_payload)->list);
216 return 0;
217}
218
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700219static enum cam_vfe_bus_comp_grp_id
220 cam_vfe_bus_comp_grp_id_convert(uint32_t comp_grp)
221{
222 switch (comp_grp) {
223 case CAM_ISP_RES_COMP_GROUP_ID_0:
224 return CAM_VFE_BUS_COMP_GROUP_ID_0;
225 case CAM_ISP_RES_COMP_GROUP_ID_1:
226 return CAM_VFE_BUS_COMP_GROUP_ID_1;
227 case CAM_ISP_RES_COMP_GROUP_ID_2:
228 return CAM_VFE_BUS_COMP_GROUP_ID_2;
229 case CAM_ISP_RES_COMP_GROUP_ID_3:
230 return CAM_VFE_BUS_COMP_GROUP_ID_3;
231 case CAM_ISP_RES_COMP_GROUP_ID_4:
232 return CAM_VFE_BUS_COMP_GROUP_ID_4;
233 case CAM_ISP_RES_COMP_GROUP_ID_5:
234 return CAM_VFE_BUS_COMP_GROUP_ID_5;
235 case CAM_ISP_RES_COMP_GROUP_NONE:
236 default:
237 return CAM_VFE_BUS_COMP_GROUP_NONE;
238 }
239}
240
Harsh Shaha1af8822017-05-11 22:06:36 -0700241static int cam_vfe_bus_put_evt_payload(void *core_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700242 struct cam_vfe_bus_irq_evt_payload **evt_payload)
243{
244 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
245 uint32_t *ife_irq_regs = NULL;
246 uint32_t status_reg0, status_reg1, status_reg2;
247
248 if (!core_info) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700249 CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
Harsh Shah19f55812017-06-26 18:58:49 -0700250 return -EINVAL;
251 }
252 if (*evt_payload == NULL) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700253 CAM_ERR(CAM_ISP, "No payload to put");
Harsh Shah19f55812017-06-26 18:58:49 -0700254 return -EINVAL;
255 }
256
257 ife_irq_regs = (*evt_payload)->irq_reg_val;
258 status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
259 status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
260 status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
261
262 if (status_reg0 || status_reg1 || status_reg2) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700263 CAM_DBG(CAM_ISP, "status0 0x%x status1 0x%x status2 0x%x",
Harsh Shah19f55812017-06-26 18:58:49 -0700264 status_reg0, status_reg1, status_reg2);
265 return 0;
266 }
267
268 common_data = core_info;
269 list_add_tail(&(*evt_payload)->list,
270 &common_data->free_payload_list);
271 *evt_payload = NULL;
272
273 return 0;
274}
Harsh Shaha1af8822017-05-11 22:06:36 -0700275
276static int cam_vfe_bus_ver2_get_intra_client_mask(
277 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
278 enum cam_vfe_bus_ver2_vfe_core_id current_core,
279 uint32_t *intra_client_mask)
280{
281 int rc = 0;
282
283 *intra_client_mask = 0;
284
285 if (dual_slave_core == current_core) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700286 CAM_ERR(CAM_ISP,
287 "Invalid params. Same core as Master and Slave");
Harsh Shaha1af8822017-05-11 22:06:36 -0700288 return -EINVAL;
289 }
290
291 switch (current_core) {
292 case CAM_VFE_BUS_VER2_VFE_CORE_0:
293 switch (dual_slave_core) {
294 case CAM_VFE_BUS_VER2_VFE_CORE_1:
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530295 *intra_client_mask = 0x3;
Harsh Shaha1af8822017-05-11 22:06:36 -0700296 break;
297 case CAM_VFE_BUS_VER2_VFE_CORE_2:
298 *intra_client_mask = 0x2;
299 break;
300 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700301 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700302 dual_slave_core);
303 rc = -EINVAL;
304 break;
305 }
306 break;
307 case CAM_VFE_BUS_VER2_VFE_CORE_1:
308 switch (dual_slave_core) {
309 case CAM_VFE_BUS_VER2_VFE_CORE_0:
310 *intra_client_mask = 0x1;
311 break;
312 case CAM_VFE_BUS_VER2_VFE_CORE_2:
313 *intra_client_mask = 0x2;
314 break;
315 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700316 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700317 dual_slave_core);
318 rc = -EINVAL;
319 break;
320 }
321 break;
322 case CAM_VFE_BUS_VER2_VFE_CORE_2:
323 switch (dual_slave_core) {
324 case CAM_VFE_BUS_VER2_VFE_CORE_0:
325 *intra_client_mask = 0x1;
326 break;
327 case CAM_VFE_BUS_VER2_VFE_CORE_1:
328 *intra_client_mask = 0x2;
329 break;
330 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700331 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700332 dual_slave_core);
333 rc = -EINVAL;
334 break;
335 }
336 break;
337 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700338 CAM_ERR(CAM_ISP,
339 "Invalid value for master core %u", current_core);
Harsh Shaha1af8822017-05-11 22:06:36 -0700340 rc = -EINVAL;
341 break;
342 }
343
344 return rc;
345}
346
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700347static bool cam_vfe_bus_can_be_secure(uint32_t out_type)
348{
349 switch (out_type) {
350 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
351 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
352 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
353 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
354 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
355 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
356 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
357 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
358 return true;
359
360 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
361 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
362 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
363 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
364 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
365 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
366 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
367 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
368 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
369 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
370 default:
371 return false;
372 }
373}
374
Harsh Shaha1af8822017-05-11 22:06:36 -0700375static enum cam_vfe_bus_ver2_vfe_out_type
376 cam_vfe_bus_get_out_res_id(uint32_t res_type)
377{
378 switch (res_type) {
379 case CAM_ISP_IFE_OUT_RES_FULL:
380 return CAM_VFE_BUS_VER2_VFE_OUT_FULL;
381 case CAM_ISP_IFE_OUT_RES_DS4:
382 return CAM_VFE_BUS_VER2_VFE_OUT_DS4;
383 case CAM_ISP_IFE_OUT_RES_DS16:
384 return CAM_VFE_BUS_VER2_VFE_OUT_DS16;
385 case CAM_ISP_IFE_OUT_RES_FD:
386 return CAM_VFE_BUS_VER2_VFE_OUT_FD;
387 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
388 return CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP;
389 case CAM_ISP_IFE_OUT_RES_PDAF:
390 return CAM_VFE_BUS_VER2_VFE_OUT_PDAF;
391 case CAM_ISP_IFE_OUT_RES_RDI_0:
392 return CAM_VFE_BUS_VER2_VFE_OUT_RDI0;
393 case CAM_ISP_IFE_OUT_RES_RDI_1:
394 return CAM_VFE_BUS_VER2_VFE_OUT_RDI1;
395 case CAM_ISP_IFE_OUT_RES_RDI_2:
396 return CAM_VFE_BUS_VER2_VFE_OUT_RDI2;
397 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
398 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE;
399 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
400 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST;
401 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
402 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG;
403 case CAM_ISP_IFE_OUT_RES_STATS_BF:
404 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF;
405 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
406 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG;
407 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
408 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST;
409 case CAM_ISP_IFE_OUT_RES_STATS_RS:
410 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS;
411 case CAM_ISP_IFE_OUT_RES_STATS_CS:
412 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS;
413 case CAM_ISP_IFE_OUT_RES_STATS_IHIST:
414 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST;
415 default:
416 return CAM_VFE_BUS_VER2_VFE_OUT_MAX;
417 }
418}
419
420static int cam_vfe_bus_get_num_wm(
421 enum cam_vfe_bus_ver2_vfe_out_type res_type,
422 uint32_t format)
423{
424 switch (res_type) {
425 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
426 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
427 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
428 switch (format) {
429 case CAM_FORMAT_MIPI_RAW_8:
430 case CAM_FORMAT_MIPI_RAW_10:
431 case CAM_FORMAT_MIPI_RAW_12:
432 case CAM_FORMAT_MIPI_RAW_14:
433 case CAM_FORMAT_MIPI_RAW_16:
434 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530435 case CAM_FORMAT_DPCM_10_6_10:
436 case CAM_FORMAT_DPCM_10_8_10:
437 case CAM_FORMAT_DPCM_12_6_12:
438 case CAM_FORMAT_DPCM_12_8_12:
439 case CAM_FORMAT_DPCM_14_8_14:
440 case CAM_FORMAT_DPCM_14_10_14:
441 case CAM_FORMAT_PLAIN8:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530442 case CAM_FORMAT_PLAIN16_10:
443 case CAM_FORMAT_PLAIN16_12:
444 case CAM_FORMAT_PLAIN16_14:
445 case CAM_FORMAT_PLAIN16_16:
446 case CAM_FORMAT_PLAIN32_20:
Harsh Shaha1af8822017-05-11 22:06:36 -0700447 case CAM_FORMAT_PLAIN128:
448 return 1;
449 default:
450 break;
451 }
452 break;
453 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
454 switch (format) {
455 case CAM_FORMAT_NV21:
456 case CAM_FORMAT_NV12:
457 case CAM_FORMAT_MIPI_RAW_8:
458 case CAM_FORMAT_PLAIN8:
459 case CAM_FORMAT_TP10:
460 case CAM_FORMAT_UBWC_NV12:
461 case CAM_FORMAT_UBWC_NV12_4R:
462 case CAM_FORMAT_UBWC_TP10:
463 case CAM_FORMAT_UBWC_P010:
464 return 2;
465 default:
466 break;
467 }
468 break;
469 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
470 switch (format) {
471 case CAM_FORMAT_NV21:
472 case CAM_FORMAT_NV12:
473 case CAM_FORMAT_PLAIN8:
474 case CAM_FORMAT_TP10:
475 case CAM_FORMAT_PLAIN16_10:
476 return 2;
477 default:
478 break;
479 }
480 break;
481 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
482 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
483 switch (format) {
484 case CAM_FORMAT_PD8:
485 case CAM_FORMAT_PD10:
486 return 1;
487 default:
488 break;
489 }
490 break;
491 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
492 switch (format) {
493 case CAM_FORMAT_ARGB_14:
494 case CAM_FORMAT_PLAIN8:
495 case CAM_FORMAT_PLAIN16_10:
496 case CAM_FORMAT_PLAIN16_12:
497 case CAM_FORMAT_PLAIN16_14:
498 return 1;
499 default:
500 break;
501 }
502 break;
503 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
504 switch (format) {
505 case CAM_FORMAT_PLAIN8:
506 case CAM_FORMAT_PLAIN16_10:
507 case CAM_FORMAT_PLAIN16_12:
508 case CAM_FORMAT_PLAIN16_14:
509 return 1;
510 default:
511 break;
512 }
513 break;
514 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
515 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
516 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
517 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
518 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
519 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
520 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
521 switch (format) {
522 case CAM_FORMAT_PLAIN64:
523 return 1;
524 default:
525 break;
526 }
527 break;
528 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
529 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
530 switch (format) {
531 case CAM_FORMAT_PLAIN16_16:
532 return 1;
533 default:
534 break;
535 }
536 break;
537 default:
538 break;
539 }
540
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700541 CAM_ERR(CAM_ISP, "Unsupported format %u for resource_type %u",
542 format, res_type);
Harsh Shaha1af8822017-05-11 22:06:36 -0700543
544 return -EINVAL;
545}
546
547static int cam_vfe_bus_get_wm_idx(
548 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
549 enum cam_vfe_bus_plane_type plane)
550{
551 int wm_idx = -1;
552
553 switch (vfe_out_res_id) {
554 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
555 switch (plane) {
556 case PLANE_Y:
557 wm_idx = 3;
558 break;
559 case PLANE_C:
560 wm_idx = 4;
561 break;
562 default:
563 break;
564 }
565 break;
566 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
567 switch (plane) {
568 case PLANE_Y:
569 wm_idx = 5;
570 break;
571 default:
572 break;
573 }
574 break;
575 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
576 switch (plane) {
577 case PLANE_Y:
578 wm_idx = 6;
579 break;
580 default:
581 break;
582 }
583 break;
584 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
585 switch (plane) {
586 case PLANE_Y:
587 wm_idx = 7;
588 break;
589 case PLANE_C:
590 wm_idx = 8;
591 break;
592 default:
593 break;
594 }
595 break;
596 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
597 switch (plane) {
598 case PLANE_Y:
599 wm_idx = 9;
600 break;
601 default:
602 break;
603 }
604 break;
605 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
606 switch (plane) {
607 case PLANE_Y:
608 wm_idx = 10;
609 break;
610 default:
611 break;
612 }
613 break;
614 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
615 switch (plane) {
616 case PLANE_Y:
617 wm_idx = 0;
618 break;
619 default:
620 break;
621 }
622 break;
623 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
624 switch (plane) {
625 case PLANE_Y:
626 wm_idx = 1;
627 break;
628 default:
629 break;
630 }
631 break;
632 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
633 switch (plane) {
634 case PLANE_Y:
635 wm_idx = 2;
636 break;
637 default:
638 break;
639 }
640 break;
641 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
642 switch (plane) {
643 case PLANE_Y:
644 wm_idx = 11;
645 break;
646 default:
647 break;
648 }
649 break;
650 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
651 switch (plane) {
652 case PLANE_Y:
653 wm_idx = 12;
654 break;
655 default:
656 break;
657 }
658 break;
659 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
660 switch (plane) {
661 case PLANE_Y:
662 wm_idx = 13;
663 break;
664 default:
665 break;
666 }
667 break;
668 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
669 switch (plane) {
670 case PLANE_Y:
671 wm_idx = 14;
672 break;
673 default:
674 break;
675 }
676 break;
677 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
678 switch (plane) {
679 case PLANE_Y:
680 wm_idx = 15;
681 break;
682 default:
683 break;
684 }
685 break;
686 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
687 switch (plane) {
688 case PLANE_Y:
689 wm_idx = 16;
690 break;
691 default:
692 break;
693 }
694 break;
695 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
696 switch (plane) {
697 case PLANE_Y:
698 wm_idx = 17;
699 break;
700 default:
701 break;
702 }
703 break;
704 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
705 switch (plane) {
706 case PLANE_Y:
707 wm_idx = 18;
708 break;
709 default:
710 break;
711 }
712 break;
713 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
714 switch (plane) {
715 case PLANE_Y:
716 wm_idx = 19;
717 break;
718 default:
719 break;
720 }
721 break;
722 default:
723 break;
724 }
725
726 return wm_idx;
727}
728
729static enum cam_vfe_bus_packer_format
730 cam_vfe_bus_get_packer_fmt(uint32_t out_fmt)
731{
732 switch (out_fmt) {
733 case CAM_FORMAT_NV21:
734 case CAM_FORMAT_NV12:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700735 case CAM_FORMAT_UBWC_NV12:
736 case CAM_FORMAT_UBWC_NV12_4R:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530737 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530738 case CAM_FORMAT_PLAIN16_16:
739 return PACKER_FMT_PLAIN_16_16BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530740 case CAM_FORMAT_PLAIN64:
741 return PACKER_FMT_PLAIN_64;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530742 case CAM_FORMAT_PLAIN8:
743 return PACKER_FMT_PLAIN_8;
744 case CAM_FORMAT_PLAIN16_10:
745 return PACKER_FMT_PLAIN_16_10BPP;
746 case CAM_FORMAT_PLAIN16_12:
747 return PACKER_FMT_PLAIN_16_12BPP;
748 case CAM_FORMAT_PLAIN16_14:
749 return PACKER_FMT_PLAIN_16_14BPP;
750 case CAM_FORMAT_PLAIN32_20:
751 return PACKER_FMT_PLAIN_32_20BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530752 case CAM_FORMAT_MIPI_RAW_6:
753 case CAM_FORMAT_MIPI_RAW_8:
754 case CAM_FORMAT_MIPI_RAW_10:
755 case CAM_FORMAT_MIPI_RAW_12:
756 case CAM_FORMAT_MIPI_RAW_14:
757 case CAM_FORMAT_MIPI_RAW_16:
758 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530759 case CAM_FORMAT_PLAIN16_8:
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530760 case CAM_FORMAT_PLAIN128:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530761 case CAM_FORMAT_PD8:
762 case CAM_FORMAT_PD10:
763 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700764 case CAM_FORMAT_UBWC_TP10:
765 case CAM_FORMAT_TP10:
766 return PACKER_FMT_TP_10;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530767 case CAM_FORMAT_ARGB_14:
768 return PACKER_FMT_ARGB_14;
Harsh Shaha1af8822017-05-11 22:06:36 -0700769 default:
770 return PACKER_FMT_MAX;
771 }
772}
773
774static int cam_vfe_bus_acquire_wm(
775 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
776 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700777 void *tasklet,
778 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700779 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
780 enum cam_vfe_bus_plane_type plane,
Harsh Shaha1af8822017-05-11 22:06:36 -0700781 uint32_t subscribe_irq,
782 struct cam_isp_resource_node **wm_res,
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530783 uint32_t *client_done_mask,
784 uint32_t is_dual)
Harsh Shaha1af8822017-05-11 22:06:36 -0700785{
786 uint32_t wm_idx = 0;
787 struct cam_isp_resource_node *wm_res_local = NULL;
788 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
789
790 *wm_res = NULL;
791 *client_done_mask = 0;
792
793 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
794 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
795 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700796 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700797 vfe_out_res_id, plane);
798 return -EINVAL;
799 }
800
801 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700802 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700803 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
804
805 rsrc_data = wm_res_local->res_priv;
806 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700807 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700808 rsrc_data->format = out_port_info->format;
809 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
810
811 rsrc_data->width = out_port_info->width;
812 rsrc_data->height = out_port_info->height;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +0530813 rsrc_data->is_dual = is_dual;
814 /* Set WM offset value to default */
815 rsrc_data->offset = 0;
Harsh Shahf7136392017-08-29 12:42:52 -0700816 CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index,
817 rsrc_data->width, rsrc_data->height);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700818
819 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700820 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Harsh Shahf7136392017-08-29 12:42:52 -0700821 switch (rsrc_data->format) {
822 case CAM_FORMAT_MIPI_RAW_6:
823 case CAM_FORMAT_MIPI_RAW_8:
824 case CAM_FORMAT_MIPI_RAW_10:
825 case CAM_FORMAT_MIPI_RAW_12:
826 case CAM_FORMAT_MIPI_RAW_14:
827 case CAM_FORMAT_MIPI_RAW_16:
828 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahea34b602017-09-29 11:42:45 -0700829 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700830 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
831 rsrc_data->height = 0;
832 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
833 rsrc_data->pack_fmt = 0x0;
834 rsrc_data->en_cfg = 0x3;
835 break;
836 case CAM_FORMAT_PLAIN8:
837 rsrc_data->en_cfg = 0x1;
838 rsrc_data->pack_fmt = 0x1;
839 rsrc_data->width = rsrc_data->width * 2;
840 rsrc_data->stride = rsrc_data->width;
841 break;
842 case CAM_FORMAT_PLAIN16_10:
843 rsrc_data->en_cfg = 0x1;
844 rsrc_data->pack_fmt = 0x2;
845 rsrc_data->width = rsrc_data->width * 2;
846 rsrc_data->stride = rsrc_data->width;
847 break;
848 case CAM_FORMAT_PLAIN16_12:
849 rsrc_data->en_cfg = 0x1;
850 rsrc_data->pack_fmt = 0x3;
851 rsrc_data->width = rsrc_data->width * 2;
852 rsrc_data->stride = rsrc_data->width;
853 break;
854 case CAM_FORMAT_PLAIN16_14:
855 rsrc_data->en_cfg = 0x1;
856 rsrc_data->pack_fmt = 0x4;
857 rsrc_data->width = rsrc_data->width * 2;
858 rsrc_data->stride = rsrc_data->width;
859 break;
860 case CAM_FORMAT_PLAIN16_16:
861 rsrc_data->en_cfg = 0x1;
862 rsrc_data->pack_fmt = 0x5;
863 rsrc_data->width = rsrc_data->width * 2;
864 rsrc_data->stride = rsrc_data->width;
865 break;
866 case CAM_FORMAT_PLAIN32_20:
867 rsrc_data->en_cfg = 0x1;
868 rsrc_data->pack_fmt = 0x9;
869 break;
870 case CAM_FORMAT_PLAIN64:
871 rsrc_data->en_cfg = 0x1;
872 rsrc_data->pack_fmt = 0xA;
873 break;
Harsh Shahf7136392017-08-29 12:42:52 -0700874 default:
875 CAM_ERR(CAM_ISP, "Unsupported RDI format %d",
876 rsrc_data->format);
877 return -EINVAL;
878 }
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530879 } else if (rsrc_data->index < 5 ||
880 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700881 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
882 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700883 case CAM_FORMAT_UBWC_NV12_4R:
884 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700885 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
886 switch (plane) {
887 case PLANE_C:
888 rsrc_data->height /= 2;
889 break;
890 case PLANE_Y:
891 break;
892 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700893 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700894 return -EINVAL;
895 }
896 break;
897 case CAM_FORMAT_UBWC_NV12:
898 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700899 /* Fall through for NV12 */
900 case CAM_FORMAT_NV21:
901 case CAM_FORMAT_NV12:
902 switch (plane) {
903 case PLANE_C:
904 rsrc_data->height /= 2;
905 break;
906 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700907 break;
908 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700909 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700910 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700911 }
912 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700913 case CAM_FORMAT_UBWC_TP10:
914 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700915 rsrc_data->width =
916 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
917 switch (plane) {
918 case PLANE_C:
919 rsrc_data->height /= 2;
920 break;
921 case PLANE_Y:
922 break;
923 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700924 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700925 return -EINVAL;
926 }
927 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700928 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700929 rsrc_data->width =
930 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700931 switch (plane) {
932 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700933 rsrc_data->height /= 2;
934 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700935 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700936 break;
937 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700938 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700939 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700940 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700941 break;
942 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700943 CAM_ERR(CAM_ISP, "Invalid format %d",
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700944 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700945 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700946 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700947 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530948 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700949 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530950 rsrc_data->width = 0;
951 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530952 rsrc_data->stride = 1;
953 rsrc_data->en_cfg = 0x3;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530954 } else if (rsrc_data->index == 9) {
955 /* Write master 9 - Raw dump */
956 rsrc_data->width = rsrc_data->width * 2;
957 rsrc_data->stride = rsrc_data->width;
958 rsrc_data->en_cfg = 0x1;
959 } else {
960 /* Write master 5-6 DS ports, 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700961 rsrc_data->width = rsrc_data->width * 4;
962 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700963 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700964 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700965
966 *client_done_mask = (1 << wm_idx);
967 *wm_res = wm_res_local;
968
969 return 0;
970}
971
972static int cam_vfe_bus_release_wm(void *bus_priv,
973 struct cam_isp_resource_node *wm_res)
974{
975 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
976 wm_res->res_priv;
977
978 rsrc_data->irq_enabled = 0;
979 rsrc_data->offset = 0;
980 rsrc_data->width = 0;
981 rsrc_data->height = 0;
982 rsrc_data->stride = 0;
983 rsrc_data->format = 0;
984 rsrc_data->pack_fmt = 0;
985 rsrc_data->burst_len = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -0700986 rsrc_data->irq_subsample_period = 0;
987 rsrc_data->irq_subsample_pattern = 0;
988 rsrc_data->framedrop_period = 0;
989 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700990 rsrc_data->packer_cfg = 0;
991 rsrc_data->en_ubwc = 0;
992 rsrc_data->tile_cfg = 0;
993 rsrc_data->h_init = 0;
994 rsrc_data->v_init = 0;
995 rsrc_data->ubwc_meta_stride = 0;
996 rsrc_data->ubwc_mode_cfg = 0;
997 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700998 rsrc_data->init_cfg_done = false;
999 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001000 rsrc_data->en_cfg = 0;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301001 rsrc_data->is_dual = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001002
1003 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001004 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1005
1006 return 0;
1007}
1008
1009static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
1010{
1011 int rc = 0;
1012 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1013 wm_res->res_priv;
1014 struct cam_vfe_bus_ver2_common_data *common_data =
1015 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001016 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001017
Harsh Shah23557ae2017-05-13 18:14:34 -07001018 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
1019 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -07001020 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
1021
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001022 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -07001023 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001024 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -07001025 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001026 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -07001027 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001028
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301029 /* Configure stride for RDIs */
1030 if (rsrc_data->index < 3)
1031 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
1032 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -07001033
Harsh Shah19f55812017-06-26 18:58:49 -07001034 /* Subscribe IRQ */
1035 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001036 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -07001037 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
1038 (1 << rsrc_data->index);
1039 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
1040 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1041 bus_irq_reg_mask, wm_res,
1042 wm_res->top_half_handler,
1043 cam_ife_mgr_do_tasklet_buf_done,
1044 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
1045 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001046 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001047 rsrc_data->index);
1048 return -EFAULT;
1049 }
1050 }
1051
Junzhe Zou3d292562017-07-12 17:59:58 -07001052 /* enable ubwc if needed*/
1053 if (rsrc_data->en_ubwc) {
1054 cam_io_w_mb(0x1, common_data->mem_base +
1055 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
1056 }
1057
Harsh Shah19f55812017-06-26 18:58:49 -07001058 /* Enable WM */
1059 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
1060 rsrc_data->hw_regs->cfg);
1061
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001062 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001063 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001064 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001065 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001066 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001067 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001068 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
1069 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
1070 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001071
1072 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1073
1074 return rc;
1075}
1076
1077static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
1078{
1079 int rc = 0;
1080 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1081 wm_res->res_priv;
1082 struct cam_vfe_bus_ver2_common_data *common_data =
1083 rsrc_data->common_data;
1084
1085 /* Disble WM */
1086 cam_io_w_mb(0x0,
1087 common_data->mem_base + rsrc_data->hw_regs->cfg);
1088
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001089 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -07001090 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001091 if (rsrc_data->irq_enabled)
1092 rc = cam_irq_controller_unsubscribe_irq(
1093 common_data->bus_irq_controller,
1094 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001095
1096 /* Halt & Reset WM */
1097 cam_io_w_mb(BIT(rsrc_data->index),
1098 common_data->mem_base + common_data->common_reg->sw_reset);
1099
1100 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1101
1102 return rc;
1103}
1104
1105static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
1106 struct cam_irq_th_payload *th_payload)
1107{
Harsh Shah19f55812017-06-26 18:58:49 -07001108 int32_t rc;
1109 int i;
1110 struct cam_isp_resource_node *wm_res = NULL;
1111 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
1112 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1113
1114 wm_res = th_payload->handler_priv;
1115 if (!wm_res) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001116 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error: No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001117 return -ENODEV;
1118 }
1119
1120 rsrc_data = wm_res->res_priv;
1121
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001122 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1123 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001124
1125 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1126 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001127 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001128 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001129 return rc;
1130 }
1131
1132 cam_isp_hw_get_timestamp(&evt_payload->ts);
1133
1134 evt_payload->ctx = rsrc_data->ctx;
1135 evt_payload->core_index = rsrc_data->common_data->core_index;
1136 evt_payload->evt_id = evt_id;
1137
1138 for (i = 0; i < th_payload->num_registers; i++)
1139 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1140
1141 th_payload->evt_payload_priv = evt_payload;
1142
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001143 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001144 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001145}
1146
1147static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1148 void *evt_payload_priv)
1149{
1150 int rc = CAM_VFE_IRQ_STATUS_ERR;
1151 struct cam_isp_resource_node *wm_res = wm_node;
1152 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001153 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1154 (wm_res == NULL) ? NULL : wm_res->res_priv;
1155 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001156 uint32_t status_reg;
1157
Harsh Shah23557ae2017-05-13 18:14:34 -07001158 if (!evt_payload || !rsrc_data)
1159 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001160
Harsh Shah23557ae2017-05-13 18:14:34 -07001161 cam_ife_irq_regs = evt_payload->irq_reg_val;
1162 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1163
1164 if (status_reg & BIT(rsrc_data->index)) {
1165 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1166 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001167 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001168 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001169 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001170
1171 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001172 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001173 &evt_payload);
1174
1175 return rc;
1176}
1177
1178static int cam_vfe_bus_init_wm_resource(uint32_t index,
1179 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1180 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1181 struct cam_isp_resource_node *wm_res)
1182{
Harsh Shaha1af8822017-05-11 22:06:36 -07001183 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1184
1185 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1186 GFP_KERNEL);
1187 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001188 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001189 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001190 }
1191 wm_res->res_priv = rsrc_data;
1192
1193 rsrc_data->index = index;
1194 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1195 rsrc_data->common_data = &ver2_bus_priv->common_data;
1196
1197 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1198 INIT_LIST_HEAD(&wm_res->list);
1199
1200 wm_res->start = cam_vfe_bus_start_wm;
1201 wm_res->stop = cam_vfe_bus_stop_wm;
1202 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1203 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1204 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1205
Harsh Shah545df9a2017-06-16 16:43:17 -07001206 return 0;
1207}
1208
1209static int cam_vfe_bus_deinit_wm_resource(
1210 struct cam_isp_resource_node *wm_res)
1211{
1212 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1213
1214 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1215 INIT_LIST_HEAD(&wm_res->list);
1216
1217 wm_res->start = NULL;
1218 wm_res->stop = NULL;
1219 wm_res->top_half_handler = NULL;
1220 wm_res->bottom_half_handler = NULL;
1221 wm_res->hw_intf = NULL;
1222
1223 rsrc_data = wm_res->res_priv;
1224 wm_res->res_priv = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001225 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07001226 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07001227 kfree(rsrc_data);
1228
1229 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001230}
1231
1232static void cam_vfe_bus_add_wm_to_comp_grp(
1233 struct cam_isp_resource_node *comp_grp,
1234 uint32_t composite_mask)
1235{
1236 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1237
1238 rsrc_data->composite_mask |= composite_mask;
1239}
1240
1241static void cam_vfe_bus_match_comp_grp(
1242 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1243 struct cam_isp_resource_node **comp_grp,
1244 uint32_t comp_grp_local_idx,
1245 uint32_t unique_id)
1246{
1247 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1248 struct cam_isp_resource_node *comp_grp_local = NULL;
1249
1250 list_for_each_entry(comp_grp_local,
1251 &ver2_bus_priv->used_comp_grp, list) {
1252 rsrc_data = comp_grp_local->res_priv;
1253 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1254 rsrc_data->unique_id == unique_id) {
1255 /* Match found */
1256 *comp_grp = comp_grp_local;
1257 return;
1258 }
1259 }
1260
1261 *comp_grp = NULL;
1262}
1263
1264static int cam_vfe_bus_acquire_comp_grp(
1265 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1266 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001267 void *tasklet,
1268 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001269 uint32_t unique_id,
1270 uint32_t is_dual,
1271 uint32_t is_master,
1272 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1273 struct cam_isp_resource_node **comp_grp)
1274{
1275 int rc = 0;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001276 uint32_t bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001277 struct cam_isp_resource_node *comp_grp_local = NULL;
1278 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1279
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001280 bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
1281 out_port_info->comp_grp_id);
1282 /* Perform match only if there is valid comp grp request */
1283 if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
1284 /* Check if matching comp_grp already acquired */
1285 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1286 bus_comp_grp_id, unique_id);
1287 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001288
1289 if (!comp_grp_local) {
1290 /* First find a free group */
1291 if (is_dual) {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301292 CAM_DBG(CAM_ISP, "Acquire dual comp group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001293 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001294 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001295 return -ENODEV;
1296 }
1297 comp_grp_local = list_first_entry(
1298 &ver2_bus_priv->free_dual_comp_grp,
1299 struct cam_isp_resource_node, list);
1300 rsrc_data = comp_grp_local->res_priv;
1301 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1302 dual_slave_core,
1303 comp_grp_local->hw_intf->hw_idx,
1304 &rsrc_data->intra_client_mask);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301305 if (rc)
1306 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001307 } else {
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301308 CAM_DBG(CAM_ISP, "Acquire comp group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001309 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001310 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001311 return -ENODEV;
1312 }
1313 comp_grp_local = list_first_entry(
1314 &ver2_bus_priv->free_comp_grp,
1315 struct cam_isp_resource_node, list);
1316 rsrc_data = comp_grp_local->res_priv;
1317 }
1318
1319 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001320 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001321 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1322
1323 rsrc_data->is_master = is_master;
1324 rsrc_data->composite_mask = 0;
1325 rsrc_data->unique_id = unique_id;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001326 rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001327
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301328 if (is_master)
1329 rsrc_data->addr_sync_mode = 0;
1330 else
1331 rsrc_data->addr_sync_mode = 1;
1332
Harsh Shaha1af8822017-05-11 22:06:36 -07001333 list_add_tail(&comp_grp_local->list,
1334 &ver2_bus_priv->used_comp_grp);
1335
1336 } else {
1337 rsrc_data = comp_grp_local->res_priv;
1338 /* Do not support runtime change in composite mask */
1339 if (comp_grp_local->res_state ==
1340 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001341 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001342 comp_grp_local->res_state,
1343 rsrc_data->comp_grp_type);
1344 return -EBUSY;
1345 }
1346 }
1347
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301348 CAM_DBG(CAM_ISP, "Comp Grp type %u", rsrc_data->comp_grp_type);
1349
Harsh Shah19f55812017-06-26 18:58:49 -07001350 rsrc_data->ctx = ctx;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001351 rsrc_data->acquire_dev_cnt++;
Harsh Shaha1af8822017-05-11 22:06:36 -07001352 *comp_grp = comp_grp_local;
1353
1354 return rc;
1355}
1356
1357static int cam_vfe_bus_release_comp_grp(
1358 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1359 struct cam_isp_resource_node *in_comp_grp)
1360{
1361 struct cam_isp_resource_node *comp_grp = NULL;
1362 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1363 int match_found = 0;
1364
1365 if (!in_comp_grp) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001366 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
Harsh Shaha1af8822017-05-11 22:06:36 -07001367 return -EINVAL;
1368 }
1369
1370 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001371 CAM_ERR(CAM_ISP, "Already released Comp Grp");
Harsh Shaha1af8822017-05-11 22:06:36 -07001372 return 0;
1373 }
1374
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001375 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
1376 CAM_ERR(CAM_ISP, "Invalid State %d",
1377 in_comp_grp->res_state);
1378 return -EBUSY;
1379 }
1380
Harsh Shaha1af8822017-05-11 22:06:36 -07001381 in_rsrc_data = in_comp_grp->res_priv;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301382 CAM_DBG(CAM_ISP, "Comp Grp type %u", in_rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001383
1384 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1385 if (comp_grp == in_comp_grp) {
1386 match_found = 1;
1387 break;
1388 }
1389 }
1390
1391 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001392 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001393 in_rsrc_data->comp_grp_type);
1394 return -ENODEV;
1395 }
1396
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001397 in_rsrc_data->acquire_dev_cnt--;
1398 if (in_rsrc_data->acquire_dev_cnt == 0) {
1399 list_del(&comp_grp->list);
Harsh Shaha1af8822017-05-11 22:06:36 -07001400
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001401 in_rsrc_data->unique_id = 0;
1402 in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
1403 in_rsrc_data->composite_mask = 0;
1404 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301405 in_rsrc_data->addr_sync_mode = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001406
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001407 comp_grp->tasklet_info = NULL;
1408 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
Harsh Shaha1af8822017-05-11 22:06:36 -07001409
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001410 if (in_rsrc_data->comp_grp_type >=
1411 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1412 in_rsrc_data->comp_grp_type <=
1413 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1414 list_add_tail(&comp_grp->list,
1415 &ver2_bus_priv->free_dual_comp_grp);
1416 else if (in_rsrc_data->comp_grp_type >=
1417 CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1418 in_rsrc_data->comp_grp_type <=
1419 CAM_VFE_BUS_VER2_COMP_GRP_5)
1420 list_add_tail(&comp_grp->list,
1421 &ver2_bus_priv->free_comp_grp);
1422 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001423
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001424 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001425}
1426
1427static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1428{
1429 int rc = 0;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301430 uint32_t addr_sync_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07001431 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1432 comp_grp->res_priv;
1433 struct cam_vfe_bus_ver2_common_data *common_data =
1434 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001435 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001436
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301437 CAM_DBG(CAM_ISP, "comp group id:%d streaming state:%d",
1438 rsrc_data->comp_grp_type, comp_grp->res_state);
1439
Harsh Shaha1af8822017-05-11 22:06:36 -07001440 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1441 rsrc_data->hw_regs->comp_mask);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301442 if (comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
1443 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001444
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001445 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1446 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1447 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001448
1449 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301450 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) {
Harsh Shaha1af8822017-05-11 22:06:36 -07001451 int dual_comp_grp = (rsrc_data->comp_grp_type -
1452 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
Harsh Shaha1af8822017-05-11 22:06:36 -07001453
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301454 if (rsrc_data->is_master) {
1455 int intra_client_en = cam_io_r_mb(
1456 common_data->mem_base +
1457 common_data->common_reg->dual_master_comp_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001458
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301459 /*
1460 * 2 Bits per comp_grp. Hence left shift by
1461 * comp_grp * 2
1462 */
1463 intra_client_en |=
1464 (rsrc_data->intra_client_mask <<
1465 (dual_comp_grp * 2));
Harsh Shah19f55812017-06-26 18:58:49 -07001466
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301467 cam_io_w_mb(intra_client_en, common_data->mem_base +
1468 common_data->common_reg->dual_master_comp_cfg);
1469
1470 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] =
1471 (1 << dual_comp_grp);
1472 }
1473
1474 CAM_DBG(CAM_ISP, "addr_sync_mask addr 0x%x",
1475 rsrc_data->hw_regs->addr_sync_mask);
1476 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1477 rsrc_data->hw_regs->addr_sync_mask);
1478
1479 addr_sync_cfg = cam_io_r_mb(common_data->mem_base +
1480 common_data->common_reg->addr_sync_cfg);
1481 addr_sync_cfg |= (rsrc_data->addr_sync_mode << dual_comp_grp);
1482 /*
1483 * 2 Bits per dual_comp_grp. dual_comp_grp stats at bit number
1484 * 8. Hence left shift cdual_comp_grp dual comp_grp * 2 and
1485 * add 8
1486 */
1487 addr_sync_cfg |=
1488 (rsrc_data->intra_client_mask <<
1489 ((dual_comp_grp * 2) +
1490 CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT));
1491 cam_io_w_mb(addr_sync_cfg, common_data->mem_base +
1492 common_data->common_reg->addr_sync_cfg);
1493
1494 common_data->addr_no_sync &= ~(rsrc_data->composite_mask);
1495 cam_io_w_mb(common_data->addr_no_sync, common_data->mem_base +
1496 common_data->common_reg->addr_sync_no_sync);
1497 CAM_DBG(CAM_ISP, "addr_sync_cfg: 0x%x addr_no_sync_cfg: 0x%x",
1498 addr_sync_cfg, common_data->addr_no_sync);
Harsh Shah19f55812017-06-26 18:58:49 -07001499 } else {
1500 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1501 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1502 (1 << (rsrc_data->comp_grp_type + 5));
1503 }
1504
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301505 /*
1506 * For Dual composite subscribe IRQ only for master
1507 * For regular composite, subscribe IRQ always
1508 */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001509 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301510 if (((rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1511 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) &&
1512 (rsrc_data->is_master)) ||
1513 (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1514 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)) {
1515 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1516 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1517 bus_irq_reg_mask, comp_grp,
1518 comp_grp->top_half_handler,
1519 cam_ife_mgr_do_tasklet_buf_done,
1520 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1521 if (comp_grp->irq_handle < 0) {
1522 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
1523 rsrc_data->comp_grp_type);
1524 return -EFAULT;
1525 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001526 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001527 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001528
Harsh Shaha1af8822017-05-11 22:06:36 -07001529 return rc;
1530}
1531
1532static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1533{
1534 int rc = 0;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301535 uint32_t addr_sync_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07001536 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1537 comp_grp->res_priv;
1538 struct cam_vfe_bus_ver2_common_data *common_data =
1539 rsrc_data->common_data;
1540
1541 /* Unsubscribe IRQ */
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301542 if (((rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1543 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) &&
1544 (rsrc_data->is_master)) ||
1545 (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1546 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)) {
1547 rc = cam_irq_controller_unsubscribe_irq(
1548 common_data->bus_irq_controller,
1549 comp_grp->irq_handle);
1550 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001551
1552 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1553 rsrc_data->hw_regs->comp_mask);
1554 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301555 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5) {
1556
Harsh Shaha1af8822017-05-11 22:06:36 -07001557 int dual_comp_grp = (rsrc_data->comp_grp_type -
1558 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
Harsh Shaha1af8822017-05-11 22:06:36 -07001559
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301560 if (rsrc_data->is_master) {
1561 int intra_client_en = cam_io_r_mb(
1562 common_data->mem_base +
1563 common_data->common_reg->dual_master_comp_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001564
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301565 /*
1566 * 2 Bits per comp_grp. Hence left shift by
1567 * comp_grp * 2
1568 */
1569 intra_client_en &=
1570 ~(rsrc_data->intra_client_mask <<
1571 dual_comp_grp * 2);
1572
1573 cam_io_w_mb(intra_client_en, common_data->mem_base +
1574 common_data->common_reg->dual_master_comp_cfg);
1575 }
1576
1577 addr_sync_cfg = cam_io_r_mb(common_data->mem_base +
1578 common_data->common_reg->addr_sync_cfg);
1579 addr_sync_cfg &= ~(1 << dual_comp_grp);
1580 addr_sync_cfg &= ~(CAM_VFE_BUS_INTRA_CLIENT_MASK <<
1581 ((dual_comp_grp * 2) +
1582 CAM_VFE_BUS_ADDR_SYNC_INTRA_CLIENT_SHIFT));
1583 cam_io_w_mb(addr_sync_cfg, common_data->mem_base +
1584 common_data->common_reg->addr_sync_cfg);
1585
1586 cam_io_w_mb(0, common_data->mem_base +
1587 rsrc_data->hw_regs->addr_sync_mask);
1588 common_data->addr_no_sync |= rsrc_data->composite_mask;
1589 cam_io_w_mb(common_data->addr_no_sync, common_data->mem_base +
1590 common_data->common_reg->addr_sync_no_sync);
1591 CAM_DBG(CAM_ISP, "addr_sync_cfg: 0x% addr_no_sync_cfg: 0x%x",
1592 addr_sync_cfg, common_data->addr_no_sync);
1593
Harsh Shaha1af8822017-05-11 22:06:36 -07001594 }
1595
1596 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1597
1598 return rc;
1599}
1600
1601static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1602 struct cam_irq_th_payload *th_payload)
1603{
Harsh Shah19f55812017-06-26 18:58:49 -07001604 int32_t rc;
1605 int i;
1606 struct cam_isp_resource_node *comp_grp = NULL;
1607 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1608 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1609
1610 comp_grp = th_payload->handler_priv;
1611 if (!comp_grp) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001612 CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001613 return -ENODEV;
1614 }
1615
1616 rsrc_data = comp_grp->res_priv;
1617
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001618 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1619 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301620 CAM_DBG(CAM_ISP, "IRQ status_2 = %x", th_payload->evt_status_arr[2]);
Harsh Shah19f55812017-06-26 18:58:49 -07001621
1622 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1623 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001624 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001625 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001626 return rc;
1627 }
1628
1629 cam_isp_hw_get_timestamp(&evt_payload->ts);
1630
1631 evt_payload->ctx = rsrc_data->ctx;
1632 evt_payload->core_index = rsrc_data->common_data->core_index;
1633 evt_payload->evt_id = evt_id;
1634
1635 for (i = 0; i < th_payload->num_registers; i++)
1636 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1637
1638 th_payload->evt_payload_priv = evt_payload;
1639
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001640 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001641 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001642}
1643
1644static int cam_vfe_bus_handle_comp_done_bottom_half(
1645 void *handler_priv,
1646 void *evt_payload_priv)
1647{
1648 int rc = CAM_VFE_IRQ_STATUS_ERR;
1649 struct cam_isp_resource_node *comp_grp = handler_priv;
1650 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1651 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001652 uint32_t *cam_ife_irq_regs;
1653 uint32_t status_reg;
1654 uint32_t comp_err_reg;
1655 uint32_t comp_grp_id;
1656
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001657 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001658
Harsh Shah23557ae2017-05-13 18:14:34 -07001659 if (!evt_payload)
1660 return rc;
1661
1662 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001663
Harsh Shaha1af8822017-05-11 22:06:36 -07001664 switch (rsrc_data->comp_grp_type) {
1665 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1666 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1667 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1668 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1669 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1670 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001671 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001672 CAM_VFE_BUS_VER2_COMP_GRP_0);
1673
1674 /* Check for Regular composite error */
1675 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1676
1677 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1678 if ((status_reg & BIT(11)) &&
1679 (comp_err_reg & rsrc_data->composite_mask)) {
1680 /* Check for Regular composite error */
1681 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1682 break;
1683 }
1684
1685 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1686 /* Check for Regular composite Overwrite */
1687 if ((status_reg & BIT(12)) &&
1688 (comp_err_reg & rsrc_data->composite_mask)) {
1689 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1690 break;
1691 }
1692
Harsh Shah23557ae2017-05-13 18:14:34 -07001693 /* Regular Composite SUCCESS */
1694 if (status_reg & BIT(comp_grp_id + 5)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001695 rsrc_data->irq_trigger_cnt++;
1696 if (rsrc_data->irq_trigger_cnt ==
1697 rsrc_data->acquire_dev_cnt) {
1698 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1699 ~BIT(comp_grp_id + 5);
1700 rsrc_data->irq_trigger_cnt = 0;
1701 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001702 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001703 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001704
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001705 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001706 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001707 break;
1708
1709 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1710 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1711 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1712 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1713 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1714 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001715 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001716 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1717
1718 /* Check for DUAL composite error */
1719 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1720
1721 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1722 if ((status_reg & BIT(6)) &&
1723 (comp_err_reg & rsrc_data->composite_mask)) {
1724 /* Check for DUAL composite error */
1725 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1726 break;
1727 }
1728
1729 /* Check for Dual composite Overwrite */
1730 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1731 if ((status_reg & BIT(7)) &&
1732 (comp_err_reg & rsrc_data->composite_mask)) {
1733 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1734 break;
1735 }
1736
Harsh Shah23557ae2017-05-13 18:14:34 -07001737 /* DUAL Composite SUCCESS */
1738 if (status_reg & BIT(comp_grp_id)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001739 rsrc_data->irq_trigger_cnt++;
1740 if (rsrc_data->irq_trigger_cnt ==
1741 rsrc_data->acquire_dev_cnt) {
1742 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301743 ~BIT(comp_grp_id);
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001744 rsrc_data->irq_trigger_cnt = 0;
1745 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001746 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001747 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001748
1749 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001750 default:
1751 rc = CAM_VFE_IRQ_STATUS_ERR;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001752 CAM_ERR(CAM_ISP, "Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001753 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001754 break;
1755 }
1756
1757 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001758 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001759 &evt_payload);
1760
1761 return rc;
1762}
1763
1764static int cam_vfe_bus_init_comp_grp(uint32_t index,
1765 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1766 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1767 struct cam_isp_resource_node *comp_grp)
1768{
Harsh Shah545df9a2017-06-16 16:43:17 -07001769 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001770
1771 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1772 GFP_KERNEL);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001773 if (!rsrc_data)
Harsh Shaha1af8822017-05-11 22:06:36 -07001774 return -ENOMEM;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001775
Harsh Shaha1af8822017-05-11 22:06:36 -07001776 comp_grp->res_priv = rsrc_data;
1777
1778 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1779 INIT_LIST_HEAD(&comp_grp->list);
1780
1781 rsrc_data->comp_grp_type = index;
1782 rsrc_data->common_data = &ver2_bus_priv->common_data;
1783 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1784 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1785
Harsh Shaha1af8822017-05-11 22:06:36 -07001786 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1787 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1788 list_add_tail(&comp_grp->list,
1789 &ver2_bus_priv->free_dual_comp_grp);
1790 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1791 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1792 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1793
1794 comp_grp->start = cam_vfe_bus_start_comp_grp;
1795 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1796 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1797 comp_grp->bottom_half_handler =
1798 cam_vfe_bus_handle_comp_done_bottom_half;
1799 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1800
1801 return 0;
1802}
1803
Harsh Shah545df9a2017-06-16 16:43:17 -07001804static int cam_vfe_bus_deinit_comp_grp(
1805 struct cam_isp_resource_node *comp_grp)
1806{
1807 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1808 comp_grp->res_priv;
1809
1810 comp_grp->start = NULL;
1811 comp_grp->stop = NULL;
1812 comp_grp->top_half_handler = NULL;
1813 comp_grp->bottom_half_handler = NULL;
1814 comp_grp->hw_intf = NULL;
1815
1816 list_del_init(&comp_grp->list);
1817 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1818
1819 comp_grp->res_priv = NULL;
1820
1821 if (!rsrc_data) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001822 CAM_ERR(CAM_ISP, "comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001823 return -ENODEV;
1824 }
1825 kfree(rsrc_data);
1826
1827 return 0;
1828}
1829
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001830static int cam_vfe_bus_get_secure_mode(void *priv, void *cmd_args,
1831 uint32_t arg_size)
1832{
1833 bool *mode = cmd_args;
1834 struct cam_isp_resource_node *res =
1835 (struct cam_isp_resource_node *) priv;
1836 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data =
1837 (struct cam_vfe_bus_ver2_vfe_out_data *)res->res_priv;
1838
1839 *mode =
1840 (rsrc_data->secure_mode == CAM_SECURE_MODE_SECURE) ?
1841 true : false;
1842
1843 return 0;
1844}
1845
Harsh Shah19f55812017-06-26 18:58:49 -07001846static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1847 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001848{
1849 int rc = -ENODEV;
1850 int i;
1851 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1852 uint32_t format;
Harsh Shahea526f82017-09-25 14:47:32 -07001853 int num_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07001854 uint32_t subscribe_irq;
1855 uint32_t client_done_mask;
1856 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1857 struct cam_vfe_acquire_args *acq_args = acquire_args;
1858 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1859 struct cam_isp_resource_node *rsrc_node = NULL;
1860 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001861 uint32_t secure_caps = 0, mode;
Harsh Shaha1af8822017-05-11 22:06:36 -07001862
1863 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001864 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001865 return -EINVAL;
1866 }
1867
1868 out_acquire_args = &acq_args->vfe_out;
1869 format = out_acquire_args->out_port_info->format;
1870
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001871 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001872 out_acquire_args->out_port_info->res_type);
1873
1874 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1875 out_acquire_args->out_port_info->res_type);
1876 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1877 return -ENODEV;
1878
1879 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1880 if (num_wm < 1)
1881 return -EINVAL;
1882
1883 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1884 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001885 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001886 vfe_out_res_id, rsrc_node->res_state);
1887 return -EBUSY;
1888 }
1889
1890 rsrc_data = rsrc_node->res_priv;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001891 secure_caps = cam_vfe_bus_can_be_secure(
1892 rsrc_data->out_type);
1893 mode = out_acquire_args->out_port_info->secure_mode;
1894 mutex_lock(&rsrc_data->common_data->bus_mutex);
1895 if (secure_caps) {
1896 if (!rsrc_data->common_data->num_sec_out) {
1897 rsrc_data->secure_mode = mode;
1898 rsrc_data->common_data->secure_mode = mode;
1899 } else {
1900 if (mode == rsrc_data->common_data->secure_mode) {
1901 rsrc_data->secure_mode =
1902 rsrc_data->common_data->secure_mode;
1903 } else {
1904 rc = -EINVAL;
1905 CAM_ERR_RATE_LIMIT(CAM_ISP,
1906 "Mismatch: Acquire mode[%d], drvr mode[%d]",
1907 rsrc_data->common_data->secure_mode,
1908 mode);
1909 mutex_unlock(
1910 &rsrc_data->common_data->bus_mutex);
1911 return -EINVAL;
1912 }
1913 }
1914 rsrc_data->common_data->num_sec_out++;
1915 }
1916 mutex_unlock(&rsrc_data->common_data->bus_mutex);
1917
Harsh Shaha1af8822017-05-11 22:06:36 -07001918 rsrc_data->num_wm = num_wm;
1919 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1920 rsrc_node->tasklet_info = acq_args->tasklet;
1921 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1922 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1923
1924 /* Reserve Composite Group */
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301925 if (num_wm > 1 || (out_acquire_args->is_dual) ||
1926 (out_acquire_args->out_port_info->comp_grp_id >
1927 CAM_ISP_RES_COMP_GROUP_NONE &&
1928 out_acquire_args->out_port_info->comp_grp_id <
1929 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1930
Harsh Shaha1af8822017-05-11 22:06:36 -07001931 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1932 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001933 acq_args->tasklet,
1934 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001935 out_acquire_args->unique_id,
1936 out_acquire_args->is_dual,
1937 out_acquire_args->is_master,
1938 out_acquire_args->dual_slave_core,
1939 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001940 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001941 CAM_ERR(CAM_ISP,
1942 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001943 rsrc_data->common_data->core_index,
1944 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001945 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001946 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001947
1948 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001949 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001950 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001951 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001952
1953 /* Reserve WM */
1954 for (i = 0; i < num_wm; i++) {
1955 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1956 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001957 acq_args->tasklet,
1958 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001959 vfe_out_res_id,
1960 i,
Harsh Shaha1af8822017-05-11 22:06:36 -07001961 subscribe_irq,
1962 &rsrc_data->wm_res[i],
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05301963 &client_done_mask,
1964 out_acquire_args->is_dual);
Harsh Shah19f55812017-06-26 18:58:49 -07001965 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001966 CAM_ERR(CAM_ISP,
1967 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001968 rsrc_data->common_data->core_index,
1969 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001970 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001971 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001972
1973 if (rsrc_data->comp_grp)
1974 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1975 client_done_mask);
1976 }
1977
1978 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1979 out_acquire_args->rsrc_node = rsrc_node;
1980
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001981 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001982 return rc;
1983
1984release_wm:
1985 for (i--; i >= 0; i--)
1986 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1987
1988 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1989 rsrc_data->comp_grp);
1990
1991 return rc;
1992}
1993
Harsh Shah19f55812017-06-26 18:58:49 -07001994static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1995 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001996{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001997 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001998 struct cam_isp_resource_node *vfe_out = NULL;
1999 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002000 uint32_t secure_caps = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07002001
2002 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002003 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07002004 bus_priv, release_args);
2005 return -EINVAL;
2006 }
2007
2008 vfe_out = release_args;
2009 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07002010
Harsh Shaha1af8822017-05-11 22:06:36 -07002011 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002012 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002013 vfe_out->res_state);
2014 }
2015
Jing Zhoue71fd4a2017-05-15 19:44:34 -07002016 for (i = 0; i < rsrc_data->num_wm; i++)
2017 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
2018 rsrc_data->num_wm = 0;
2019
2020 if (rsrc_data->comp_grp)
2021 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
2022 rsrc_data->comp_grp = NULL;
2023
2024 vfe_out->tasklet_info = NULL;
2025 vfe_out->cdm_ops = NULL;
2026 rsrc_data->cdm_util_ops = NULL;
2027
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002028 secure_caps = cam_vfe_bus_can_be_secure(rsrc_data->out_type);
2029 mutex_lock(&rsrc_data->common_data->bus_mutex);
2030 if (secure_caps) {
2031 if (rsrc_data->secure_mode ==
2032 rsrc_data->common_data->secure_mode) {
2033 rsrc_data->common_data->num_sec_out--;
2034 rsrc_data->secure_mode =
2035 CAM_SECURE_MODE_NON_SECURE;
2036 } else {
2037 /*
2038 * The validity of the mode is properly
2039 * checked while acquiring the output port.
2040 * not expected to reach here, unless there is
2041 * some corruption.
2042 */
2043 CAM_ERR(CAM_ISP, "driver[%d],resource[%d] mismatch",
2044 rsrc_data->common_data->secure_mode,
2045 rsrc_data->secure_mode);
2046 }
2047
2048 if (!rsrc_data->common_data->num_sec_out)
2049 rsrc_data->common_data->secure_mode =
2050 CAM_SECURE_MODE_NON_SECURE;
2051 }
2052 mutex_unlock(&rsrc_data->common_data->bus_mutex);
2053
Harsh Shaha1af8822017-05-11 22:06:36 -07002054 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
2055 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2056
2057 return 0;
2058}
2059
Harsh Shah19f55812017-06-26 18:58:49 -07002060static int cam_vfe_bus_start_vfe_out(
2061 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07002062{
2063 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07002064 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2065 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
2066
2067 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002068 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07002069 return -EINVAL;
2070 }
2071
2072 rsrc_data = vfe_out->res_priv;
2073 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07002074
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002075 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07002076
2077 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002078 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002079 vfe_out->res_state);
2080 return -EACCES;
2081 }
2082
2083 for (i = 0; i < rsrc_data->num_wm; i++)
2084 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
2085
2086 if (rsrc_data->comp_grp)
2087 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
2088
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05302089 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07002090 return rc;
2091}
2092
Harsh Shah19f55812017-06-26 18:58:49 -07002093static int cam_vfe_bus_stop_vfe_out(
2094 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07002095{
2096 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07002097 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2098
2099 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002100 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07002101 return -EINVAL;
2102 }
2103
2104 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002105
2106 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
2107 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
2108 return rc;
2109 }
2110
2111 if (rsrc_data->comp_grp)
2112 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
2113
2114 for (i = 0; i < rsrc_data->num_wm; i++)
2115 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
2116
Harsh Shaha1af8822017-05-11 22:06:36 -07002117 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
2118 return rc;
2119}
2120
2121static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
2122 struct cam_irq_th_payload *th_payload)
2123{
2124 return -EPERM;
2125}
2126
2127static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
2128 void *handler_priv,
2129 void *evt_payload_priv)
2130{
2131 int rc = -EINVAL;
2132 struct cam_isp_resource_node *vfe_out = handler_priv;
2133 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2134
2135 /*
2136 * If this resource has Composite Group then we only handle
2137 * Composite done. We acquire Composite if number of WM > 1.
2138 * So Else case is only one individual buf_done = WM[0].
2139 */
2140 if (rsrc_data->comp_grp) {
2141 rc = rsrc_data->comp_grp->bottom_half_handler(
2142 rsrc_data->comp_grp, evt_payload_priv);
2143 } else {
2144 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07002145 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07002146 }
2147
2148 return rc;
2149}
2150
2151static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
2152 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
2153 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
2154 struct cam_isp_resource_node *vfe_out)
2155{
2156 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2157 int rc = 0;
2158
2159 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
2160 GFP_KERNEL);
2161 if (!rsrc_data) {
Harsh Shaha1af8822017-05-11 22:06:36 -07002162 rc = -ENOMEM;
2163 return rc;
2164 }
2165 vfe_out->res_priv = rsrc_data;
2166
2167 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
2168 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2169 INIT_LIST_HEAD(&vfe_out->list);
2170
2171 rsrc_data->out_type = index;
2172 rsrc_data->common_data = &ver2_bus_priv->common_data;
2173 rsrc_data->max_width =
2174 ver2_hw_info->vfe_out_hw_info[index].max_width;
2175 rsrc_data->max_height =
2176 ver2_hw_info->vfe_out_hw_info[index].max_height;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002177 rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shaha1af8822017-05-11 22:06:36 -07002178
2179 vfe_out->start = cam_vfe_bus_start_vfe_out;
2180 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
2181 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
2182 vfe_out->bottom_half_handler =
2183 cam_vfe_bus_handle_vfe_out_done_bottom_half;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002184 vfe_out->process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002185 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
2186
2187 return 0;
2188}
2189
Harsh Shah545df9a2017-06-16 16:43:17 -07002190static int cam_vfe_bus_deinit_vfe_out_resource(
2191 struct cam_isp_resource_node *vfe_out)
2192{
2193 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2194
2195 vfe_out->start = NULL;
2196 vfe_out->stop = NULL;
2197 vfe_out->top_half_handler = NULL;
2198 vfe_out->bottom_half_handler = NULL;
2199 vfe_out->hw_intf = NULL;
2200
2201 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
2202 INIT_LIST_HEAD(&vfe_out->list);
2203 vfe_out->res_priv = NULL;
2204
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002205 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07002206 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002207 kfree(rsrc_data);
2208
2209 return 0;
2210}
2211
Harsh Shaha1af8822017-05-11 22:06:36 -07002212static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
2213 struct cam_irq_th_payload *th_payload)
2214{
Harsh Shaha1af8822017-05-11 22:06:36 -07002215 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002216
Harsh Shah19f55812017-06-26 18:58:49 -07002217 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002218 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07002219 return cam_irq_controller_handle_irq(evt_id,
2220 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07002221}
2222
2223static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
2224 uint32_t arg_size)
2225{
2226 struct cam_vfe_bus_ver2_priv *bus_priv;
2227 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002228 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07002229 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2230 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002231 uint32_t *reg_val_pair;
2232 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07002233 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07002234
Harsh Shaha1af8822017-05-11 22:06:36 -07002235 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2236 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
2237
2238 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2239 update_buf->cdm.res->res_priv;
2240
2241 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002242 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07002243 return -EINVAL;
2244 }
2245
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002246 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002247 CAM_ERR(CAM_ISP,
2248 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002249 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07002250 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07002251 }
2252
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002253 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2254 io_cfg = update_buf->io_cfg;
2255
2256 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07002257 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002258 CAM_ERR(CAM_ISP,
2259 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07002260 j, MAX_REG_VAL_PAIR_SIZE);
2261 return -ENOMEM;
2262 }
2263
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002264 wm_data = vfe_out_data->wm_res[i]->res_priv;
2265
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302266 /* update width register */
2267 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2268 wm_data->hw_regs->buffer_width_cfg,
2269 wm_data->width);
2270 CAM_DBG(CAM_ISP, "image width 0x%x", wm_data->width);
2271
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002272 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302273 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
2274 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002275 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2276 wm_data->hw_regs->stride,
2277 io_cfg->planes[i].plane_stride);
2278 wm_data->stride = io_cfg->planes[i].plane_stride;
2279 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002280 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002281
2282 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002283 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002284 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2285 wm_data->hw_regs->framedrop_pattern,
2286 io_cfg->framedrop_pattern);
2287 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
2288 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002289 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2290 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002291
2292 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002293 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002294 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2295 wm_data->hw_regs->framedrop_period,
2296 io_cfg->framedrop_period);
2297 wm_data->framedrop_period = io_cfg->framedrop_period;
2298 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002299 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2300 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002301
2302 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002303 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002304 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2305 wm_data->hw_regs->irq_subsample_period,
2306 io_cfg->subsample_period);
2307 wm_data->irq_subsample_period =
2308 io_cfg->subsample_period;
2309 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002310 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002311 wm_data->irq_subsample_period);
2312
2313 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002314 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002315 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2316 wm_data->hw_regs->irq_subsample_pattern,
2317 io_cfg->subsample_pattern);
2318 wm_data->irq_subsample_pattern =
2319 io_cfg->subsample_pattern;
2320 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002321 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002322 wm_data->irq_subsample_pattern);
2323
2324 if (wm_data->en_ubwc) {
2325 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002326 CAM_ERR(CAM_ISP,
2327 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002328 return -EINVAL;
2329 }
2330 if (wm_data->packer_cfg !=
2331 io_cfg->planes[i].packer_config ||
2332 !wm_data->init_cfg_done) {
2333 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2334 wm_data->hw_regs->packer_cfg,
2335 io_cfg->planes[i].packer_config);
2336 wm_data->packer_cfg =
2337 io_cfg->planes[i].packer_config;
2338 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002339 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2340 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002341
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302342 if (wm_data->is_dual) {
2343 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2344 wm_data->hw_regs->ubwc_regs->tile_cfg,
2345 wm_data->tile_cfg);
2346 } else if ((wm_data->tile_cfg !=
2347 io_cfg->planes[i].tile_config)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002348 || !wm_data->init_cfg_done) {
2349 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2350 wm_data->hw_regs->ubwc_regs->tile_cfg,
2351 io_cfg->planes[i].tile_config);
2352 wm_data->tile_cfg =
2353 io_cfg->planes[i].tile_config;
2354 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002355 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002356
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302357 if (wm_data->is_dual) {
2358 if ((wm_data->h_init != wm_data->offset) ||
2359 !wm_data->init_cfg_done) {
2360 /*
2361 * For dual ife h init value need to take from
2362 * offset.Striping config update offset value
2363 */
2364 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair,
2365 j,
2366 wm_data->hw_regs->ubwc_regs->
2367 h_init,
2368 wm_data->offset);
2369 wm_data->h_init = wm_data->offset;
2370 }
2371 } else if (wm_data->h_init !=
2372 io_cfg->planes[i].h_init ||
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002373 !wm_data->init_cfg_done) {
2374 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2375 wm_data->hw_regs->ubwc_regs->h_init,
2376 io_cfg->planes[i].h_init);
2377 wm_data->h_init = io_cfg->planes[i].h_init;
2378 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002379 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002380
2381 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2382 !wm_data->init_cfg_done) {
2383 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2384 wm_data->hw_regs->ubwc_regs->v_init,
2385 io_cfg->planes[i].v_init);
2386 wm_data->v_init = io_cfg->planes[i].v_init;
2387 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002388 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002389
2390 if (wm_data->ubwc_meta_stride !=
2391 io_cfg->planes[i].meta_stride ||
2392 !wm_data->init_cfg_done) {
2393 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2394 wm_data->hw_regs->ubwc_regs->
2395 meta_stride,
2396 io_cfg->planes[i].meta_stride);
2397 wm_data->ubwc_meta_stride =
2398 io_cfg->planes[i].meta_stride;
2399 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002400 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2401 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002402
2403 if (wm_data->ubwc_mode_cfg !=
2404 io_cfg->planes[i].mode_config ||
2405 !wm_data->init_cfg_done) {
2406 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2407 wm_data->hw_regs->ubwc_regs->mode_cfg,
2408 io_cfg->planes[i].mode_config);
2409 wm_data->ubwc_mode_cfg =
2410 io_cfg->planes[i].mode_config;
2411 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002412 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2413 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002414
2415 if (wm_data->ubwc_meta_offset !=
2416 io_cfg->planes[i].meta_offset ||
2417 !wm_data->init_cfg_done) {
2418 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2419 wm_data->hw_regs->ubwc_regs->
2420 meta_offset,
2421 io_cfg->planes[i].meta_offset);
2422 wm_data->ubwc_meta_offset =
2423 io_cfg->planes[i].meta_offset;
2424 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002425 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002426 wm_data->ubwc_meta_offset);
2427
2428 /* UBWC meta address */
2429 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2430 wm_data->hw_regs->ubwc_regs->meta_addr,
2431 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002432 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002433 update_buf->image_buf[i]);
2434 }
2435
2436 /* WM Image address */
2437 if (wm_data->en_ubwc)
2438 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2439 wm_data->hw_regs->image_addr,
2440 (update_buf->image_buf[i] +
2441 io_cfg->planes[i].meta_size));
2442 else
2443 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302444 wm_data->hw_regs->image_addr,
2445 update_buf->image_buf[i] +
2446 wm_data->offset);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002447
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002448 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002449
Junzhe Zou193d78c2017-05-16 15:10:54 -07002450 frame_inc = io_cfg->planes[i].plane_stride *
2451 io_cfg->planes[i].slice_height;
2452 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2453 wm_data->hw_regs->frame_inc, frame_inc);
2454
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002455 /* enable the WM */
2456 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2457 wm_data->hw_regs->cfg,
2458 wm_data->en_cfg);
2459
2460 /* set initial configuration done */
2461 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002462 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002463 }
2464
2465 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002466
2467 /* cdm util returns dwords, need to convert to bytes */
2468 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002469 CAM_ERR(CAM_ISP,
2470 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002471 update_buf->cdm.size, size);
2472 return -ENOMEM;
2473 }
2474
Harsh Shaha1af8822017-05-11 22:06:36 -07002475 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002476 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2477
Harsh Shaha1af8822017-05-11 22:06:36 -07002478 /* cdm util returns dwords, need to convert to bytes */
2479 update_buf->cdm.used_bytes = size * 4;
2480
2481 return 0;
2482}
2483
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002484static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2485 uint32_t arg_size)
2486{
2487 struct cam_vfe_bus_ver2_priv *bus_priv;
2488 struct cam_isp_hw_get_hfr_update *update_hfr;
2489 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2490 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2491 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2492 uint32_t *reg_val_pair;
2493 uint32_t i, j, size = 0;
2494
2495 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2496 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2497
2498 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2499 update_hfr->cdm.res->res_priv;
2500
2501 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2502 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2503 return -EINVAL;
2504 }
2505
2506 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2507 hfr_cfg = update_hfr->io_hfr_cfg;
2508
2509 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2510 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2511 CAM_ERR(CAM_ISP,
2512 "reg_val_pair %d exceeds the array limit %lu",
2513 j, MAX_REG_VAL_PAIR_SIZE);
2514 return -ENOMEM;
2515 }
2516
2517 wm_data = vfe_out_data->wm_res[i]->res_priv;
2518
2519 if ((wm_data->framedrop_pattern !=
2520 hfr_cfg->framedrop_pattern) ||
2521 !wm_data->hfr_cfg_done) {
2522 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2523 wm_data->hw_regs->framedrop_pattern,
2524 hfr_cfg->framedrop_pattern);
2525 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2526 }
2527 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2528 wm_data->framedrop_pattern);
2529
2530 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2531 !wm_data->hfr_cfg_done) {
2532 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2533 wm_data->hw_regs->framedrop_period,
2534 hfr_cfg->framedrop_period);
2535 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2536 }
2537 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2538 wm_data->framedrop_period);
2539
2540 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2541 || !wm_data->hfr_cfg_done) {
2542 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2543 wm_data->hw_regs->irq_subsample_period,
2544 hfr_cfg->subsample_period);
2545 wm_data->irq_subsample_period =
2546 hfr_cfg->subsample_period;
2547 }
2548 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2549 wm_data->irq_subsample_period);
2550
2551 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2552 || !wm_data->hfr_cfg_done) {
2553 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2554 wm_data->hw_regs->irq_subsample_pattern,
2555 hfr_cfg->subsample_pattern);
2556 wm_data->irq_subsample_pattern =
2557 hfr_cfg->subsample_pattern;
2558 }
2559 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2560 wm_data->irq_subsample_pattern);
2561
2562 /* set initial configuration done */
2563 if (!wm_data->hfr_cfg_done)
2564 wm_data->hfr_cfg_done = true;
2565 }
2566
2567 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2568
2569 /* cdm util returns dwords, need to convert to bytes */
2570 if ((size * 4) > update_hfr->cdm.size) {
2571 CAM_ERR(CAM_ISP,
2572 "Failed! Buf size:%d insufficient, expected size:%d",
2573 update_hfr->cdm.size, size);
2574 return -ENOMEM;
2575 }
2576
2577 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2578 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2579
2580 /* cdm util returns dwords, need to convert to bytes */
2581 update_hfr->cdm.used_bytes = size * 4;
2582
2583 return 0;
2584}
2585
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302586static int cam_vfe_bus_update_stripe_cfg(void *priv, void *cmd_args,
2587 uint32_t arg_size)
2588{
2589 struct cam_vfe_bus_ver2_priv *bus_priv;
2590 struct cam_isp_hw_dual_isp_update_args *stripe_args;
2591 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2592 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2593 struct cam_isp_dual_stripe_config *stripe_config;
2594 uint32_t outport_id, ports_plane_idx, i;
2595
2596 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2597 stripe_args = (struct cam_isp_hw_dual_isp_update_args *)cmd_args;
2598
2599 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2600 stripe_args->res->res_priv;
2601
2602 if (!vfe_out_data) {
2603 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2604 return -EINVAL;
2605 }
2606
2607 outport_id = stripe_args->res->res_id & 0xFF;
2608 if (stripe_args->res->res_id < CAM_ISP_IFE_OUT_RES_BASE ||
2609 stripe_args->res->res_id >= CAM_ISP_IFE_OUT_RES_MAX)
2610 return 0;
2611
2612 ports_plane_idx = (stripe_args->split_id *
2613 (stripe_args->dual_cfg->num_ports * CAM_PACKET_MAX_PLANES)) +
2614 (outport_id * CAM_PACKET_MAX_PLANES);
2615 for (i = 0; i < vfe_out_data->num_wm; i++) {
2616 wm_data = vfe_out_data->wm_res[i]->res_priv;
2617 stripe_config = (struct cam_isp_dual_stripe_config *)
2618 &stripe_args->dual_cfg->stripes[ports_plane_idx + i];
2619 wm_data->width = stripe_config->width;
2620 wm_data->offset = stripe_config->offset;
2621 wm_data->tile_cfg = stripe_config->tileconfig;
2622 CAM_DBG(CAM_ISP, "id:%x wm:%d width:0x%x offset:%x tilecfg:%x",
2623 stripe_args->res->res_id, i, wm_data->width,
2624 wm_data->offset, wm_data->tile_cfg);
2625 }
2626
2627 return 0;
2628}
2629
Harsh Shah19f55812017-06-26 18:58:49 -07002630static int cam_vfe_bus_start_hw(void *hw_priv,
2631 void *start_hw_args, uint32_t arg_size)
2632{
2633 return cam_vfe_bus_start_vfe_out(hw_priv);
2634}
2635
2636static int cam_vfe_bus_stop_hw(void *hw_priv,
2637 void *stop_hw_args, uint32_t arg_size)
2638{
2639 return cam_vfe_bus_stop_vfe_out(hw_priv);
2640}
2641
2642static int cam_vfe_bus_init_hw(void *hw_priv,
2643 void *init_hw_args, uint32_t arg_size)
2644{
2645 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2646 uint32_t top_irq_reg_mask[2] = {0};
2647
2648 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002649 CAM_ERR(CAM_ISP, "Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002650 return -EINVAL;
2651 }
2652
2653 top_irq_reg_mask[0] = (1 << 9);
2654
2655 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2656 bus_priv->common_data.vfe_irq_controller,
2657 CAM_IRQ_PRIORITY_2,
2658 top_irq_reg_mask,
2659 bus_priv,
2660 cam_vfe_bus_ver2_handle_irq,
2661 NULL,
2662 NULL,
2663 NULL);
2664
2665 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002666 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002667 return -EFAULT;
2668 }
2669
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302670 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
2671 cam_io_w_mb(0x0, bus_priv->common_data.mem_base +
2672 bus_priv->common_data.common_reg->addr_sync_frame_hdr);
2673
2674 /* no clock gating at bus input */
2675 cam_io_w_mb(0xFFFFF, bus_priv->common_data.mem_base + 0x0000200C);
2676
2677 /* BUS_WR_TEST_BUS_CTRL */
2678 cam_io_w_mb(0x0, bus_priv->common_data.mem_base + 0x0000211C);
2679
2680 /* if addr_no_sync has default value then config the addr no sync reg */
2681 cam_io_w_mb(CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL,
2682 bus_priv->common_data.mem_base +
2683 bus_priv->common_data.common_reg->addr_sync_no_sync);
2684
Harsh Shah19f55812017-06-26 18:58:49 -07002685 return 0;
2686}
2687
2688static int cam_vfe_bus_deinit_hw(void *hw_priv,
2689 void *deinit_hw_args, uint32_t arg_size)
2690{
2691 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2692 int rc;
2693
2694 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002695 CAM_ERR(CAM_ISP, "Error: Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002696 return -EINVAL;
2697 }
2698
2699 rc = cam_irq_controller_unsubscribe_irq(
2700 bus_priv->common_data.vfe_irq_controller,
2701 bus_priv->irq_handle);
2702 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002703 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002704
2705 return rc;
2706}
2707
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002708static int __cam_vfe_bus_process_cmd(void *priv,
2709 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2710{
2711 return cam_vfe_bus_process_cmd(priv, cmd_type, cmd_args, arg_size);
2712}
2713
2714static int cam_vfe_bus_process_cmd(
2715 struct cam_isp_resource_node *priv,
Harsh Shaha1af8822017-05-11 22:06:36 -07002716 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2717{
2718 int rc = -EINVAL;
2719
2720 if (!priv || !cmd_args) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002721 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
Harsh Shaha1af8822017-05-11 22:06:36 -07002722 return -EINVAL;
2723 }
2724
2725 switch (cmd_type) {
2726 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2727 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2728 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002729 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2730 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2731 break;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002732 case CAM_VFE_HW_CMD_GET_SECURE_MODE:
2733 rc = cam_vfe_bus_get_secure_mode(priv, cmd_args, arg_size);
2734 break;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302735 case CAM_VFE_HW_CMD_STRIPE_UPDATE:
2736 rc = cam_vfe_bus_update_stripe_cfg(priv, cmd_args, arg_size);
2737 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002738 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002739 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002740 cmd_type);
2741 break;
2742 }
2743
2744 return rc;
2745}
2746
2747int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002748 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002749 struct cam_hw_intf *hw_intf,
2750 void *bus_hw_info,
2751 void *vfe_irq_controller,
2752 struct cam_vfe_bus **vfe_bus)
2753{
2754 int i, rc = 0;
2755 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2756 struct cam_vfe_bus *vfe_bus_local;
2757 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2758
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002759 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002760
Harsh Shah19f55812017-06-26 18:58:49 -07002761 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002762 CAM_ERR(CAM_ISP,
2763 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2764 soc_info, hw_intf, bus_hw_info);
2765 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002766 rc = -EINVAL;
2767 goto end;
2768 }
2769
Harsh Shaha1af8822017-05-11 22:06:36 -07002770 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2771 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002772 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002773 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002774 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002775 }
2776
2777 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2778 GFP_KERNEL);
2779 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002780 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002781 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002782 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002783 }
2784 vfe_bus_local->bus_priv = bus_priv;
2785
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002786 bus_priv->common_data.num_sec_out = 0;
2787 bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shah19f55812017-06-26 18:58:49 -07002788 bus_priv->common_data.core_index = soc_info->index;
2789 bus_priv->common_data.mem_base =
2790 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002791 bus_priv->common_data.hw_intf = hw_intf;
2792 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2793 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
Ravikishore Pampanaff6132e2017-07-27 15:32:31 +05302794 bus_priv->common_data.addr_no_sync =
2795 CAM_VFE_BUS_ADDR_NO_SYNC_DEFAULT_VAL;
2796
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002797 mutex_init(&bus_priv->common_data.bus_mutex);
Harsh Shaha1af8822017-05-11 22:06:36 -07002798
Harsh Shah19f55812017-06-26 18:58:49 -07002799 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2800 &ver2_hw_info->common_reg.irq_reg_info,
2801 &bus_priv->common_data.bus_irq_controller);
2802 if (rc) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002803 CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002804 goto free_bus_priv;
2805 }
2806
Harsh Shaha1af8822017-05-11 22:06:36 -07002807 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2808 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2809 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2810
2811 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2812 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2813 &bus_priv->bus_client[i]);
2814 if (rc < 0) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002815 CAM_ERR(CAM_ISP, "Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002816 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002817 }
2818 }
2819
2820 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2821 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2822 &bus_priv->comp_grp[i]);
2823 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002824 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002825 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002826 }
2827 }
2828
2829 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2830 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2831 &bus_priv->vfe_out[i]);
2832 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002833 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002834 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002835 }
2836 }
2837
Harsh Shah19f55812017-06-26 18:58:49 -07002838 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2839 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2840 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2841 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2842 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002843 }
2844
Harsh Shah19f55812017-06-26 18:58:49 -07002845 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2846 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2847 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2848 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2849 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2850 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2851 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002852 vfe_bus_local->bottom_half_handler = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002853 vfe_bus_local->hw_ops.process_cmd = __cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002854
2855 *vfe_bus = vfe_bus_local;
2856
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002857 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002858 return rc;
2859
Harsh Shah545df9a2017-06-16 16:43:17 -07002860deinit_vfe_out:
2861 if (i < 0)
2862 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2863 for (--i; i >= 0; i--)
2864 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2865
2866deinit_comp_grp:
2867 if (i < 0)
2868 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2869 for (--i; i >= 0; i--)
2870 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2871
2872deinit_wm:
2873 if (i < 0)
2874 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2875 for (--i; i >= 0; i--)
2876 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2877
Harsh Shah19f55812017-06-26 18:58:49 -07002878free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002879 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002880
2881free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002882 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002883
2884end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002885 return rc;
2886}
Harsh Shah545df9a2017-06-16 16:43:17 -07002887
2888int cam_vfe_bus_ver2_deinit(
2889 struct cam_vfe_bus **vfe_bus)
2890{
2891 int i, rc = 0;
2892 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2893 struct cam_vfe_bus *vfe_bus_local;
2894
2895 if (!vfe_bus || !*vfe_bus) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002896 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002897 return -EINVAL;
2898 }
2899 vfe_bus_local = *vfe_bus;
2900
2901 bus_priv = vfe_bus_local->bus_priv;
2902 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002903 CAM_ERR(CAM_ISP, "bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002904 rc = -ENODEV;
2905 goto free_bus_local;
2906 }
2907
Harsh Shah19f55812017-06-26 18:58:49 -07002908 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2909 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2910 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002911
2912 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2913 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2914 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002915 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002916 "Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002917 }
2918
2919 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2920 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2921 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002922 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002923 "Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002924 }
2925
2926 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2927 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2928 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002929 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002930 "Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002931 }
2932
2933 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2934 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2935 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2936
Harsh Shah19f55812017-06-26 18:58:49 -07002937 rc = cam_irq_controller_deinit(
2938 &bus_priv->common_data.bus_irq_controller);
2939 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002940 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002941 "Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002942
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002943 mutex_destroy(&bus_priv->common_data.bus_mutex);
Harsh Shah545df9a2017-06-16 16:43:17 -07002944 kfree(vfe_bus_local->bus_priv);
2945
2946free_bus_local:
2947 kfree(vfe_bus_local);
2948
2949 *vfe_bus = NULL;
2950
2951 return rc;
2952}
2953