blob: 71994b92da98ae2a3548329ed73a11d2923fba0c [file] [log] [blame]
Harsh Shaha1af8822017-05-11 22:06:36 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Harsh Shaha1af8822017-05-11 22:06:36 -070013#include <linux/ratelimit.h>
14#include <linux/slab.h>
15#include "cam_io_util.h"
Harsh Shahf7136392017-08-29 12:42:52 -070016#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070017#include "cam_cdm_util.h"
18#include "cam_hw_intf.h"
Harsh Shah19f55812017-06-26 18:58:49 -070019#include "cam_ife_hw_mgr.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070020#include "cam_vfe_hw_intf.h"
21#include "cam_irq_controller.h"
Harsh Shah19f55812017-06-26 18:58:49 -070022#include "cam_tasklet_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070023#include "cam_vfe_bus.h"
24#include "cam_vfe_bus_ver2.h"
25#include "cam_vfe_core.h"
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -070026#include "cam_debug_util.h"
Harsh Shaha1af8822017-05-11 22:06:36 -070027
Harsh Shah19f55812017-06-26 18:58:49 -070028static const char drv_name[] = "vfe_bus";
29
30#define CAM_VFE_BUS_IRQ_REG0 0
31#define CAM_VFE_BUS_IRQ_REG1 1
32#define CAM_VFE_BUS_IRQ_REG2 2
33#define CAM_VFE_BUS_IRQ_MAX 3
34
35#define CAM_VFE_BUS_VER2_PAYLOAD_MAX 256
Harsh Shah23557ae2017-05-13 18:14:34 -070036
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +053037#define CAM_VFE_RDI_BUS_DEFAULT_WIDTH 0xFF01
38#define CAM_VFE_RDI_BUS_DEFAULT_STRIDE 0xFF01
39
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -070040#define ALIGNUP(value, alignment) \
41 ((value + alignment - 1) / alignment * alignment)
42
Junzhe Zou193d78c2017-05-16 15:10:54 -070043#define MAX_BUF_UPDATE_REG_NUM \
44 (sizeof(struct cam_vfe_bus_ver2_reg_offset_bus_client)/4)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070045#define MAX_REG_VAL_PAIR_SIZE \
Harsh Shah19f55812017-06-26 18:58:49 -070046 (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES)
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070047
48#define CAM_VFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \
Harsh Shah19f55812017-06-26 18:58:49 -070049 do { \
50 buf_array[index++] = offset; \
51 buf_array[index++] = val; \
52 } while (0)
Harsh Shaha1af8822017-05-11 22:06:36 -070053
54enum cam_vfe_bus_packer_format {
55 PACKER_FMT_PLAIN_128 = 0x0,
56 PACKER_FMT_PLAIN_8 = 0x1,
57 PACKER_FMT_PLAIN_16_10BPP = 0x2,
58 PACKER_FMT_PLAIN_16_12BPP = 0x3,
59 PACKER_FMT_PLAIN_16_14BPP = 0x4,
60 PACKER_FMT_PLAIN_16_16BPP = 0x5,
61 PACKER_FMT_ARGB_10 = 0x6,
62 PACKER_FMT_ARGB_12 = 0x7,
63 PACKER_FMT_ARGB_14 = 0x8,
64 PACKER_FMT_PLAIN_32_20BPP = 0x9,
65 PACKER_FMT_PLAIN_64 = 0xA,
66 PACKER_FMT_TP_10 = 0xB,
67 PACKER_FMT_PLAIN_32_32BPP = 0xC,
68 PACKER_FMT_PLAIN_8_ODD_EVEN = 0xD,
69 PACKER_FMT_PLAIN_8_LSB_MSB_10 = 0xE,
70 PACKER_FMT_PLAIN_8_LSB_MSB_10_ODD_EVEN = 0xF,
71 PACKER_FMT_MAX = 0xF,
72};
73
Karthik Anantha Ram01974172017-09-01 10:42:22 -070074enum cam_vfe_bus_comp_grp_id {
75 CAM_VFE_BUS_COMP_GROUP_NONE = -EINVAL,
76 CAM_VFE_BUS_COMP_GROUP_ID_0 = 0x0,
77 CAM_VFE_BUS_COMP_GROUP_ID_1 = 0x1,
78 CAM_VFE_BUS_COMP_GROUP_ID_2 = 0x2,
79 CAM_VFE_BUS_COMP_GROUP_ID_3 = 0x3,
80 CAM_VFE_BUS_COMP_GROUP_ID_4 = 0x4,
81 CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5,
82};
83
Harsh Shaha1af8822017-05-11 22:06:36 -070084struct cam_vfe_bus_ver2_common_data {
Harsh Shah19f55812017-06-26 18:58:49 -070085 uint32_t core_index;
Harsh Shaha1af8822017-05-11 22:06:36 -070086 void __iomem *mem_base;
87 struct cam_hw_intf *hw_intf;
88 void *bus_irq_controller;
89 void *vfe_irq_controller;
90 struct cam_vfe_bus_ver2_reg_offset_common *common_reg;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -070091 uint32_t io_buf_update[
Harsh Shah19f55812017-06-26 18:58:49 -070092 MAX_REG_VAL_PAIR_SIZE];
93
94 struct cam_vfe_bus_irq_evt_payload evt_payload[
95 CAM_VFE_BUS_VER2_PAYLOAD_MAX];
96 struct list_head free_payload_list;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -070097 struct mutex bus_mutex;
98 uint32_t secure_mode;
99 uint32_t num_sec_out;
Harsh Shaha1af8822017-05-11 22:06:36 -0700100};
101
102struct cam_vfe_bus_ver2_wm_resource_data {
103 uint32_t index;
104 struct cam_vfe_bus_ver2_common_data *common_data;
105 struct cam_vfe_bus_ver2_reg_offset_bus_client *hw_regs;
Harsh Shah19f55812017-06-26 18:58:49 -0700106 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700107
108 uint32_t irq_enabled;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700109 bool init_cfg_done;
110 bool hfr_cfg_done;
Harsh Shah19f55812017-06-26 18:58:49 -0700111
Harsh Shaha1af8822017-05-11 22:06:36 -0700112 uint32_t offset;
113 uint32_t width;
114 uint32_t height;
115 uint32_t stride;
116 uint32_t format;
117 enum cam_vfe_bus_packer_format pack_fmt;
118
119 uint32_t burst_len;
Harsh Shaha1af8822017-05-11 22:06:36 -0700120
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700121 uint32_t en_ubwc;
122 uint32_t packer_cfg;
123 uint32_t tile_cfg;
124 uint32_t h_init;
125 uint32_t v_init;
126 uint32_t ubwc_meta_stride;
127 uint32_t ubwc_mode_cfg;
128 uint32_t ubwc_meta_offset;
129
Harsh Shaha1af8822017-05-11 22:06:36 -0700130 uint32_t irq_subsample_period;
131 uint32_t irq_subsample_pattern;
132 uint32_t framedrop_period;
133 uint32_t framedrop_pattern;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700134
135 uint32_t en_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -0700136};
137
138struct cam_vfe_bus_ver2_comp_grp_data {
139 enum cam_vfe_bus_ver2_comp_grp_type comp_grp_type;
140 struct cam_vfe_bus_ver2_common_data *common_data;
141 struct cam_vfe_bus_ver2_reg_offset_comp_grp *hw_regs;
142
143 uint32_t irq_enabled;
144 uint32_t comp_grp_local_idx;
145 uint32_t unique_id;
146
147 uint32_t is_master;
148 uint32_t dual_slave_core;
149 uint32_t intra_client_mask;
150 uint32_t composite_mask;
Harsh Shah19f55812017-06-26 18:58:49 -0700151
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700152 uint32_t acquire_dev_cnt;
153 uint32_t irq_trigger_cnt;
154
Harsh Shah19f55812017-06-26 18:58:49 -0700155 void *ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700156};
157
158struct cam_vfe_bus_ver2_vfe_out_data {
159 uint32_t out_type;
160 struct cam_vfe_bus_ver2_common_data *common_data;
161
162 uint32_t num_wm;
163 struct cam_isp_resource_node *wm_res[PLANE_MAX];
164
165 struct cam_isp_resource_node *comp_grp;
166 enum cam_isp_hw_sync_mode dual_comp_sync_mode;
167 uint32_t dual_hw_alternate_vfe_id;
168 struct list_head vfe_out_list;
169
170 uint32_t format;
171 uint32_t max_width;
172 uint32_t max_height;
173 struct cam_cdm_utils_ops *cdm_util_ops;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700174 uint32_t secure_mode;
Harsh Shaha1af8822017-05-11 22:06:36 -0700175};
176
Harsh Shaha1af8822017-05-11 22:06:36 -0700177struct cam_vfe_bus_ver2_priv {
178 struct cam_vfe_bus_ver2_common_data common_data;
179
180 struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS];
181 struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX];
182 struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX];
183
184 struct list_head free_comp_grp;
185 struct list_head free_dual_comp_grp;
186 struct list_head used_comp_grp;
187
Harsh Shah19f55812017-06-26 18:58:49 -0700188 uint32_t irq_handle;
Harsh Shaha1af8822017-05-11 22:06:36 -0700189};
190
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700191static int cam_vfe_bus_process_cmd(
192 struct cam_isp_resource_node *priv,
193 uint32_t cmd_type, void *cmd_args, uint32_t arg_size);
194
Harsh Shah19f55812017-06-26 18:58:49 -0700195static int cam_vfe_bus_get_evt_payload(
196 struct cam_vfe_bus_ver2_common_data *common_data,
197 struct cam_vfe_bus_irq_evt_payload **evt_payload)
198{
199 if (list_empty(&common_data->free_payload_list)) {
200 *evt_payload = NULL;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700201 CAM_ERR(CAM_ISP, "No free payload");
Harsh Shah19f55812017-06-26 18:58:49 -0700202 return -ENODEV;
203 }
204
205 *evt_payload = list_first_entry(&common_data->free_payload_list,
206 struct cam_vfe_bus_irq_evt_payload, list);
207 list_del_init(&(*evt_payload)->list);
208 return 0;
209}
210
Karthik Anantha Ram01974172017-09-01 10:42:22 -0700211static enum cam_vfe_bus_comp_grp_id
212 cam_vfe_bus_comp_grp_id_convert(uint32_t comp_grp)
213{
214 switch (comp_grp) {
215 case CAM_ISP_RES_COMP_GROUP_ID_0:
216 return CAM_VFE_BUS_COMP_GROUP_ID_0;
217 case CAM_ISP_RES_COMP_GROUP_ID_1:
218 return CAM_VFE_BUS_COMP_GROUP_ID_1;
219 case CAM_ISP_RES_COMP_GROUP_ID_2:
220 return CAM_VFE_BUS_COMP_GROUP_ID_2;
221 case CAM_ISP_RES_COMP_GROUP_ID_3:
222 return CAM_VFE_BUS_COMP_GROUP_ID_3;
223 case CAM_ISP_RES_COMP_GROUP_ID_4:
224 return CAM_VFE_BUS_COMP_GROUP_ID_4;
225 case CAM_ISP_RES_COMP_GROUP_ID_5:
226 return CAM_VFE_BUS_COMP_GROUP_ID_5;
227 case CAM_ISP_RES_COMP_GROUP_NONE:
228 default:
229 return CAM_VFE_BUS_COMP_GROUP_NONE;
230 }
231}
232
Harsh Shaha1af8822017-05-11 22:06:36 -0700233static int cam_vfe_bus_put_evt_payload(void *core_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700234 struct cam_vfe_bus_irq_evt_payload **evt_payload)
235{
236 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
237 uint32_t *ife_irq_regs = NULL;
238 uint32_t status_reg0, status_reg1, status_reg2;
239
240 if (!core_info) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700241 CAM_ERR(CAM_ISP, "Invalid param core_info NULL");
Harsh Shah19f55812017-06-26 18:58:49 -0700242 return -EINVAL;
243 }
244 if (*evt_payload == NULL) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700245 CAM_ERR(CAM_ISP, "No payload to put");
Harsh Shah19f55812017-06-26 18:58:49 -0700246 return -EINVAL;
247 }
248
249 ife_irq_regs = (*evt_payload)->irq_reg_val;
250 status_reg0 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
251 status_reg1 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
252 status_reg2 = ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
253
254 if (status_reg0 || status_reg1 || status_reg2) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700255 CAM_DBG(CAM_ISP, "status0 0x%x status1 0x%x status2 0x%x",
Harsh Shah19f55812017-06-26 18:58:49 -0700256 status_reg0, status_reg1, status_reg2);
257 return 0;
258 }
259
260 common_data = core_info;
261 list_add_tail(&(*evt_payload)->list,
262 &common_data->free_payload_list);
263 *evt_payload = NULL;
264
265 return 0;
266}
Harsh Shaha1af8822017-05-11 22:06:36 -0700267
268static int cam_vfe_bus_ver2_get_intra_client_mask(
269 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
270 enum cam_vfe_bus_ver2_vfe_core_id current_core,
271 uint32_t *intra_client_mask)
272{
273 int rc = 0;
274
275 *intra_client_mask = 0;
276
277 if (dual_slave_core == current_core) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700278 CAM_ERR(CAM_ISP,
279 "Invalid params. Same core as Master and Slave");
Harsh Shaha1af8822017-05-11 22:06:36 -0700280 return -EINVAL;
281 }
282
283 switch (current_core) {
284 case CAM_VFE_BUS_VER2_VFE_CORE_0:
285 switch (dual_slave_core) {
286 case CAM_VFE_BUS_VER2_VFE_CORE_1:
287 *intra_client_mask = 0x1;
288 break;
289 case CAM_VFE_BUS_VER2_VFE_CORE_2:
290 *intra_client_mask = 0x2;
291 break;
292 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700293 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700294 dual_slave_core);
295 rc = -EINVAL;
296 break;
297 }
298 break;
299 case CAM_VFE_BUS_VER2_VFE_CORE_1:
300 switch (dual_slave_core) {
301 case CAM_VFE_BUS_VER2_VFE_CORE_0:
302 *intra_client_mask = 0x1;
303 break;
304 case CAM_VFE_BUS_VER2_VFE_CORE_2:
305 *intra_client_mask = 0x2;
306 break;
307 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700308 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700309 dual_slave_core);
310 rc = -EINVAL;
311 break;
312 }
313 break;
314 case CAM_VFE_BUS_VER2_VFE_CORE_2:
315 switch (dual_slave_core) {
316 case CAM_VFE_BUS_VER2_VFE_CORE_0:
317 *intra_client_mask = 0x1;
318 break;
319 case CAM_VFE_BUS_VER2_VFE_CORE_1:
320 *intra_client_mask = 0x2;
321 break;
322 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700323 CAM_ERR(CAM_ISP, "Invalid value for slave core %u",
Harsh Shaha1af8822017-05-11 22:06:36 -0700324 dual_slave_core);
325 rc = -EINVAL;
326 break;
327 }
328 break;
329 default:
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700330 CAM_ERR(CAM_ISP,
331 "Invalid value for master core %u", current_core);
Harsh Shaha1af8822017-05-11 22:06:36 -0700332 rc = -EINVAL;
333 break;
334 }
335
336 return rc;
337}
338
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700339static bool cam_vfe_bus_can_be_secure(uint32_t out_type)
340{
341 switch (out_type) {
342 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
343 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
344 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
345 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
346 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
347 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
348 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
349 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
350 return true;
351
352 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
353 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
354 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
355 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
356 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
357 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
358 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
359 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
360 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
361 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
362 default:
363 return false;
364 }
365}
366
Harsh Shaha1af8822017-05-11 22:06:36 -0700367static enum cam_vfe_bus_ver2_vfe_out_type
368 cam_vfe_bus_get_out_res_id(uint32_t res_type)
369{
370 switch (res_type) {
371 case CAM_ISP_IFE_OUT_RES_FULL:
372 return CAM_VFE_BUS_VER2_VFE_OUT_FULL;
373 case CAM_ISP_IFE_OUT_RES_DS4:
374 return CAM_VFE_BUS_VER2_VFE_OUT_DS4;
375 case CAM_ISP_IFE_OUT_RES_DS16:
376 return CAM_VFE_BUS_VER2_VFE_OUT_DS16;
377 case CAM_ISP_IFE_OUT_RES_FD:
378 return CAM_VFE_BUS_VER2_VFE_OUT_FD;
379 case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
380 return CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP;
381 case CAM_ISP_IFE_OUT_RES_PDAF:
382 return CAM_VFE_BUS_VER2_VFE_OUT_PDAF;
383 case CAM_ISP_IFE_OUT_RES_RDI_0:
384 return CAM_VFE_BUS_VER2_VFE_OUT_RDI0;
385 case CAM_ISP_IFE_OUT_RES_RDI_1:
386 return CAM_VFE_BUS_VER2_VFE_OUT_RDI1;
387 case CAM_ISP_IFE_OUT_RES_RDI_2:
388 return CAM_VFE_BUS_VER2_VFE_OUT_RDI2;
389 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
390 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE;
391 case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
392 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST;
393 case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
394 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG;
395 case CAM_ISP_IFE_OUT_RES_STATS_BF:
396 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF;
397 case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
398 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG;
399 case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
400 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST;
401 case CAM_ISP_IFE_OUT_RES_STATS_RS:
402 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS;
403 case CAM_ISP_IFE_OUT_RES_STATS_CS:
404 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS;
405 case CAM_ISP_IFE_OUT_RES_STATS_IHIST:
406 return CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST;
407 default:
408 return CAM_VFE_BUS_VER2_VFE_OUT_MAX;
409 }
410}
411
412static int cam_vfe_bus_get_num_wm(
413 enum cam_vfe_bus_ver2_vfe_out_type res_type,
414 uint32_t format)
415{
416 switch (res_type) {
417 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
418 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
419 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
420 switch (format) {
421 case CAM_FORMAT_MIPI_RAW_8:
422 case CAM_FORMAT_MIPI_RAW_10:
423 case CAM_FORMAT_MIPI_RAW_12:
424 case CAM_FORMAT_MIPI_RAW_14:
425 case CAM_FORMAT_MIPI_RAW_16:
426 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530427 case CAM_FORMAT_DPCM_10_6_10:
428 case CAM_FORMAT_DPCM_10_8_10:
429 case CAM_FORMAT_DPCM_12_6_12:
430 case CAM_FORMAT_DPCM_12_8_12:
431 case CAM_FORMAT_DPCM_14_8_14:
432 case CAM_FORMAT_DPCM_14_10_14:
433 case CAM_FORMAT_PLAIN8:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530434 case CAM_FORMAT_PLAIN16_10:
435 case CAM_FORMAT_PLAIN16_12:
436 case CAM_FORMAT_PLAIN16_14:
437 case CAM_FORMAT_PLAIN16_16:
438 case CAM_FORMAT_PLAIN32_20:
Harsh Shaha1af8822017-05-11 22:06:36 -0700439 case CAM_FORMAT_PLAIN128:
440 return 1;
441 default:
442 break;
443 }
444 break;
445 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
446 switch (format) {
447 case CAM_FORMAT_NV21:
448 case CAM_FORMAT_NV12:
449 case CAM_FORMAT_MIPI_RAW_8:
450 case CAM_FORMAT_PLAIN8:
451 case CAM_FORMAT_TP10:
452 case CAM_FORMAT_UBWC_NV12:
453 case CAM_FORMAT_UBWC_NV12_4R:
454 case CAM_FORMAT_UBWC_TP10:
455 case CAM_FORMAT_UBWC_P010:
456 return 2;
457 default:
458 break;
459 }
460 break;
461 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
462 switch (format) {
463 case CAM_FORMAT_NV21:
464 case CAM_FORMAT_NV12:
465 case CAM_FORMAT_PLAIN8:
466 case CAM_FORMAT_TP10:
467 case CAM_FORMAT_PLAIN16_10:
468 return 2;
469 default:
470 break;
471 }
472 break;
473 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
474 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
475 switch (format) {
476 case CAM_FORMAT_PD8:
477 case CAM_FORMAT_PD10:
478 return 1;
479 default:
480 break;
481 }
482 break;
483 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
484 switch (format) {
485 case CAM_FORMAT_ARGB_14:
486 case CAM_FORMAT_PLAIN8:
487 case CAM_FORMAT_PLAIN16_10:
488 case CAM_FORMAT_PLAIN16_12:
489 case CAM_FORMAT_PLAIN16_14:
490 return 1;
491 default:
492 break;
493 }
494 break;
495 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
496 switch (format) {
497 case CAM_FORMAT_PLAIN8:
498 case CAM_FORMAT_PLAIN16_10:
499 case CAM_FORMAT_PLAIN16_12:
500 case CAM_FORMAT_PLAIN16_14:
501 return 1;
502 default:
503 break;
504 }
505 break;
506 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
507 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
508 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
509 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
510 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
511 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
512 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
513 switch (format) {
514 case CAM_FORMAT_PLAIN64:
515 return 1;
516 default:
517 break;
518 }
519 break;
520 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
521 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
522 switch (format) {
523 case CAM_FORMAT_PLAIN16_16:
524 return 1;
525 default:
526 break;
527 }
528 break;
529 default:
530 break;
531 }
532
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700533 CAM_ERR(CAM_ISP, "Unsupported format %u for resource_type %u",
534 format, res_type);
Harsh Shaha1af8822017-05-11 22:06:36 -0700535
536 return -EINVAL;
537}
538
539static int cam_vfe_bus_get_wm_idx(
540 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
541 enum cam_vfe_bus_plane_type plane)
542{
543 int wm_idx = -1;
544
545 switch (vfe_out_res_id) {
546 case CAM_VFE_BUS_VER2_VFE_OUT_FULL:
547 switch (plane) {
548 case PLANE_Y:
549 wm_idx = 3;
550 break;
551 case PLANE_C:
552 wm_idx = 4;
553 break;
554 default:
555 break;
556 }
557 break;
558 case CAM_VFE_BUS_VER2_VFE_OUT_DS4:
559 switch (plane) {
560 case PLANE_Y:
561 wm_idx = 5;
562 break;
563 default:
564 break;
565 }
566 break;
567 case CAM_VFE_BUS_VER2_VFE_OUT_DS16:
568 switch (plane) {
569 case PLANE_Y:
570 wm_idx = 6;
571 break;
572 default:
573 break;
574 }
575 break;
576 case CAM_VFE_BUS_VER2_VFE_OUT_FD:
577 switch (plane) {
578 case PLANE_Y:
579 wm_idx = 7;
580 break;
581 case PLANE_C:
582 wm_idx = 8;
583 break;
584 default:
585 break;
586 }
587 break;
588 case CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP:
589 switch (plane) {
590 case PLANE_Y:
591 wm_idx = 9;
592 break;
593 default:
594 break;
595 }
596 break;
597 case CAM_VFE_BUS_VER2_VFE_OUT_PDAF:
598 switch (plane) {
599 case PLANE_Y:
600 wm_idx = 10;
601 break;
602 default:
603 break;
604 }
605 break;
606 case CAM_VFE_BUS_VER2_VFE_OUT_RDI0:
607 switch (plane) {
608 case PLANE_Y:
609 wm_idx = 0;
610 break;
611 default:
612 break;
613 }
614 break;
615 case CAM_VFE_BUS_VER2_VFE_OUT_RDI1:
616 switch (plane) {
617 case PLANE_Y:
618 wm_idx = 1;
619 break;
620 default:
621 break;
622 }
623 break;
624 case CAM_VFE_BUS_VER2_VFE_OUT_RDI2:
625 switch (plane) {
626 case PLANE_Y:
627 wm_idx = 2;
628 break;
629 default:
630 break;
631 }
632 break;
633 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE:
634 switch (plane) {
635 case PLANE_Y:
636 wm_idx = 11;
637 break;
638 default:
639 break;
640 }
641 break;
642 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST:
643 switch (plane) {
644 case PLANE_Y:
645 wm_idx = 12;
646 break;
647 default:
648 break;
649 }
650 break;
651 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG:
652 switch (plane) {
653 case PLANE_Y:
654 wm_idx = 13;
655 break;
656 default:
657 break;
658 }
659 break;
660 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF:
661 switch (plane) {
662 case PLANE_Y:
663 wm_idx = 14;
664 break;
665 default:
666 break;
667 }
668 break;
669 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG:
670 switch (plane) {
671 case PLANE_Y:
672 wm_idx = 15;
673 break;
674 default:
675 break;
676 }
677 break;
678 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST:
679 switch (plane) {
680 case PLANE_Y:
681 wm_idx = 16;
682 break;
683 default:
684 break;
685 }
686 break;
687 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS:
688 switch (plane) {
689 case PLANE_Y:
690 wm_idx = 17;
691 break;
692 default:
693 break;
694 }
695 break;
696 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS:
697 switch (plane) {
698 case PLANE_Y:
699 wm_idx = 18;
700 break;
701 default:
702 break;
703 }
704 break;
705 case CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST:
706 switch (plane) {
707 case PLANE_Y:
708 wm_idx = 19;
709 break;
710 default:
711 break;
712 }
713 break;
714 default:
715 break;
716 }
717
718 return wm_idx;
719}
720
721static enum cam_vfe_bus_packer_format
722 cam_vfe_bus_get_packer_fmt(uint32_t out_fmt)
723{
724 switch (out_fmt) {
725 case CAM_FORMAT_NV21:
726 case CAM_FORMAT_NV12:
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700727 case CAM_FORMAT_UBWC_NV12:
728 case CAM_FORMAT_UBWC_NV12_4R:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530729 return PACKER_FMT_PLAIN_8_LSB_MSB_10;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530730 case CAM_FORMAT_PLAIN16_16:
731 return PACKER_FMT_PLAIN_16_16BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530732 case CAM_FORMAT_PLAIN64:
733 return PACKER_FMT_PLAIN_64;
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530734 case CAM_FORMAT_PLAIN8:
735 return PACKER_FMT_PLAIN_8;
736 case CAM_FORMAT_PLAIN16_10:
737 return PACKER_FMT_PLAIN_16_10BPP;
738 case CAM_FORMAT_PLAIN16_12:
739 return PACKER_FMT_PLAIN_16_12BPP;
740 case CAM_FORMAT_PLAIN16_14:
741 return PACKER_FMT_PLAIN_16_14BPP;
742 case CAM_FORMAT_PLAIN32_20:
743 return PACKER_FMT_PLAIN_32_20BPP;
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530744 case CAM_FORMAT_MIPI_RAW_6:
745 case CAM_FORMAT_MIPI_RAW_8:
746 case CAM_FORMAT_MIPI_RAW_10:
747 case CAM_FORMAT_MIPI_RAW_12:
748 case CAM_FORMAT_MIPI_RAW_14:
749 case CAM_FORMAT_MIPI_RAW_16:
750 case CAM_FORMAT_MIPI_RAW_20:
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +0530751 case CAM_FORMAT_PLAIN16_8:
Ravikishore Pampana5286dba2017-08-31 16:19:18 +0530752 case CAM_FORMAT_PLAIN128:
Abhishek Kondaveeti170c8122017-07-06 04:45:12 +0530753 case CAM_FORMAT_PD8:
754 case CAM_FORMAT_PD10:
755 return PACKER_FMT_PLAIN_128;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700756 case CAM_FORMAT_UBWC_TP10:
757 case CAM_FORMAT_TP10:
758 return PACKER_FMT_TP_10;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530759 case CAM_FORMAT_ARGB_14:
760 return PACKER_FMT_ARGB_14;
Harsh Shaha1af8822017-05-11 22:06:36 -0700761 default:
762 return PACKER_FMT_MAX;
763 }
764}
765
766static int cam_vfe_bus_acquire_wm(
767 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
768 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -0700769 void *tasklet,
770 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -0700771 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id,
772 enum cam_vfe_bus_plane_type plane,
773 enum cam_isp_hw_split_id split_id,
774 uint32_t subscribe_irq,
775 struct cam_isp_resource_node **wm_res,
776 uint32_t *client_done_mask)
777{
778 uint32_t wm_idx = 0;
779 struct cam_isp_resource_node *wm_res_local = NULL;
780 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
781
782 *wm_res = NULL;
783 *client_done_mask = 0;
784
785 /* No need to allocate for BUS VER2. VFE OUT to WM is fixed. */
786 wm_idx = cam_vfe_bus_get_wm_idx(vfe_out_res_id, plane);
787 if (wm_idx < 0 || wm_idx >= CAM_VFE_BUS_VER2_MAX_CLIENTS) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -0700788 CAM_ERR(CAM_ISP, "Unsupported VFE out %d plane %d",
Harsh Shaha1af8822017-05-11 22:06:36 -0700789 vfe_out_res_id, plane);
790 return -EINVAL;
791 }
792
793 wm_res_local = &ver2_bus_priv->bus_client[wm_idx];
Harsh Shah19f55812017-06-26 18:58:49 -0700794 wm_res_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -0700795 wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
796
797 rsrc_data = wm_res_local->res_priv;
798 rsrc_data->irq_enabled = subscribe_irq;
Harsh Shah19f55812017-06-26 18:58:49 -0700799 rsrc_data->ctx = ctx;
Harsh Shaha1af8822017-05-11 22:06:36 -0700800 rsrc_data->format = out_port_info->format;
801 rsrc_data->pack_fmt = cam_vfe_bus_get_packer_fmt(rsrc_data->format);
802
803 rsrc_data->width = out_port_info->width;
804 rsrc_data->height = out_port_info->height;
Harsh Shahf7136392017-08-29 12:42:52 -0700805 CAM_DBG(CAM_ISP, "WM %d width %d height %d", rsrc_data->index,
806 rsrc_data->width, rsrc_data->height);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700807
808 if (rsrc_data->index < 3) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700809 /* Write master 0-2 refers to RDI 0/ RDI 1/RDI 2 */
Harsh Shahf7136392017-08-29 12:42:52 -0700810 switch (rsrc_data->format) {
811 case CAM_FORMAT_MIPI_RAW_6:
812 case CAM_FORMAT_MIPI_RAW_8:
813 case CAM_FORMAT_MIPI_RAW_10:
814 case CAM_FORMAT_MIPI_RAW_12:
815 case CAM_FORMAT_MIPI_RAW_14:
816 case CAM_FORMAT_MIPI_RAW_16:
817 case CAM_FORMAT_MIPI_RAW_20:
Harsh Shahea34b602017-09-29 11:42:45 -0700818 case CAM_FORMAT_PLAIN128:
Harsh Shahf7136392017-08-29 12:42:52 -0700819 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
820 rsrc_data->height = 0;
821 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
822 rsrc_data->pack_fmt = 0x0;
823 rsrc_data->en_cfg = 0x3;
824 break;
825 case CAM_FORMAT_PLAIN8:
826 rsrc_data->en_cfg = 0x1;
827 rsrc_data->pack_fmt = 0x1;
828 rsrc_data->width = rsrc_data->width * 2;
829 rsrc_data->stride = rsrc_data->width;
830 break;
831 case CAM_FORMAT_PLAIN16_10:
832 rsrc_data->en_cfg = 0x1;
833 rsrc_data->pack_fmt = 0x2;
834 rsrc_data->width = rsrc_data->width * 2;
835 rsrc_data->stride = rsrc_data->width;
836 break;
837 case CAM_FORMAT_PLAIN16_12:
838 rsrc_data->en_cfg = 0x1;
839 rsrc_data->pack_fmt = 0x3;
840 rsrc_data->width = rsrc_data->width * 2;
841 rsrc_data->stride = rsrc_data->width;
842 break;
843 case CAM_FORMAT_PLAIN16_14:
844 rsrc_data->en_cfg = 0x1;
845 rsrc_data->pack_fmt = 0x4;
846 rsrc_data->width = rsrc_data->width * 2;
847 rsrc_data->stride = rsrc_data->width;
848 break;
849 case CAM_FORMAT_PLAIN16_16:
850 rsrc_data->en_cfg = 0x1;
851 rsrc_data->pack_fmt = 0x5;
852 rsrc_data->width = rsrc_data->width * 2;
853 rsrc_data->stride = rsrc_data->width;
854 break;
855 case CAM_FORMAT_PLAIN32_20:
856 rsrc_data->en_cfg = 0x1;
857 rsrc_data->pack_fmt = 0x9;
858 break;
859 case CAM_FORMAT_PLAIN64:
860 rsrc_data->en_cfg = 0x1;
861 rsrc_data->pack_fmt = 0xA;
862 break;
Harsh Shahf7136392017-08-29 12:42:52 -0700863 default:
864 CAM_ERR(CAM_ISP, "Unsupported RDI format %d",
865 rsrc_data->format);
866 return -EINVAL;
867 }
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530868 } else if (rsrc_data->index < 5 ||
869 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700870 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
871 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700872 case CAM_FORMAT_UBWC_NV12_4R:
873 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700874 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
875 switch (plane) {
876 case PLANE_C:
877 rsrc_data->height /= 2;
878 break;
879 case PLANE_Y:
880 break;
881 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700882 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700883 return -EINVAL;
884 }
885 break;
886 case CAM_FORMAT_UBWC_NV12:
887 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700888 /* Fall through for NV12 */
889 case CAM_FORMAT_NV21:
890 case CAM_FORMAT_NV12:
891 switch (plane) {
892 case PLANE_C:
893 rsrc_data->height /= 2;
894 break;
895 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700896 break;
897 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700898 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700899 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700900 }
901 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700902 case CAM_FORMAT_UBWC_TP10:
903 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700904 rsrc_data->width =
905 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
906 switch (plane) {
907 case PLANE_C:
908 rsrc_data->height /= 2;
909 break;
910 case PLANE_Y:
911 break;
912 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700913 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700914 return -EINVAL;
915 }
916 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700917 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700918 rsrc_data->width =
919 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700920 switch (plane) {
921 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700922 rsrc_data->height /= 2;
923 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700924 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700925 break;
926 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700927 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700928 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700929 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700930 break;
931 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700932 CAM_ERR(CAM_ISP, "Invalid format %d",
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700933 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700934 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700935 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700936 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530937 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700938 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530939 rsrc_data->width = 0;
940 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530941 rsrc_data->stride = 1;
942 rsrc_data->en_cfg = 0x3;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530943 } else if (rsrc_data->index == 9) {
944 /* Write master 9 - Raw dump */
945 rsrc_data->width = rsrc_data->width * 2;
946 rsrc_data->stride = rsrc_data->width;
947 rsrc_data->en_cfg = 0x1;
948 } else {
949 /* Write master 5-6 DS ports, 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700950 rsrc_data->width = rsrc_data->width * 4;
951 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700952 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700953 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700954
955 *client_done_mask = (1 << wm_idx);
956 *wm_res = wm_res_local;
957
958 return 0;
959}
960
961static int cam_vfe_bus_release_wm(void *bus_priv,
962 struct cam_isp_resource_node *wm_res)
963{
964 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
965 wm_res->res_priv;
966
967 rsrc_data->irq_enabled = 0;
968 rsrc_data->offset = 0;
969 rsrc_data->width = 0;
970 rsrc_data->height = 0;
971 rsrc_data->stride = 0;
972 rsrc_data->format = 0;
973 rsrc_data->pack_fmt = 0;
974 rsrc_data->burst_len = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -0700975 rsrc_data->irq_subsample_period = 0;
976 rsrc_data->irq_subsample_pattern = 0;
977 rsrc_data->framedrop_period = 0;
978 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700979 rsrc_data->packer_cfg = 0;
980 rsrc_data->en_ubwc = 0;
981 rsrc_data->tile_cfg = 0;
982 rsrc_data->h_init = 0;
983 rsrc_data->v_init = 0;
984 rsrc_data->ubwc_meta_stride = 0;
985 rsrc_data->ubwc_mode_cfg = 0;
986 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700987 rsrc_data->init_cfg_done = false;
988 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700989 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700990
991 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700992 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
993
994 return 0;
995}
996
997static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
998{
999 int rc = 0;
1000 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1001 wm_res->res_priv;
1002 struct cam_vfe_bus_ver2_common_data *common_data =
1003 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001004 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001005
Harsh Shah23557ae2017-05-13 18:14:34 -07001006 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
1007 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -07001008 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
1009
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001010 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -07001011 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001012 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -07001013 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001014 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -07001015 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001016
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301017 /* Configure stride for RDIs */
1018 if (rsrc_data->index < 3)
1019 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
1020 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -07001021
Harsh Shah19f55812017-06-26 18:58:49 -07001022 /* Subscribe IRQ */
1023 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001024 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -07001025 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
1026 (1 << rsrc_data->index);
1027 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
1028 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1029 bus_irq_reg_mask, wm_res,
1030 wm_res->top_half_handler,
1031 cam_ife_mgr_do_tasklet_buf_done,
1032 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
1033 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001034 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001035 rsrc_data->index);
1036 return -EFAULT;
1037 }
1038 }
1039
Junzhe Zou3d292562017-07-12 17:59:58 -07001040 /* enable ubwc if needed*/
1041 if (rsrc_data->en_ubwc) {
1042 cam_io_w_mb(0x1, common_data->mem_base +
1043 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
1044 }
1045
Harsh Shah19f55812017-06-26 18:58:49 -07001046 /* Enable WM */
1047 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
1048 rsrc_data->hw_regs->cfg);
1049
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001050 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001051 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001052 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001053 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001054 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001055 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001056 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
1057 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
1058 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001059
1060 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1061
1062 return rc;
1063}
1064
1065static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
1066{
1067 int rc = 0;
1068 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1069 wm_res->res_priv;
1070 struct cam_vfe_bus_ver2_common_data *common_data =
1071 rsrc_data->common_data;
1072
1073 /* Disble WM */
1074 cam_io_w_mb(0x0,
1075 common_data->mem_base + rsrc_data->hw_regs->cfg);
1076
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001077 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -07001078 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001079 if (rsrc_data->irq_enabled)
1080 rc = cam_irq_controller_unsubscribe_irq(
1081 common_data->bus_irq_controller,
1082 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001083
1084 /* Halt & Reset WM */
1085 cam_io_w_mb(BIT(rsrc_data->index),
1086 common_data->mem_base + common_data->common_reg->sw_reset);
1087
1088 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1089
1090 return rc;
1091}
1092
1093static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
1094 struct cam_irq_th_payload *th_payload)
1095{
Harsh Shah19f55812017-06-26 18:58:49 -07001096 int32_t rc;
1097 int i;
1098 struct cam_isp_resource_node *wm_res = NULL;
1099 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
1100 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1101
1102 wm_res = th_payload->handler_priv;
1103 if (!wm_res) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001104 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error: No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001105 return -ENODEV;
1106 }
1107
1108 rsrc_data = wm_res->res_priv;
1109
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001110 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1111 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001112
1113 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1114 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001115 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001116 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001117 return rc;
1118 }
1119
1120 cam_isp_hw_get_timestamp(&evt_payload->ts);
1121
1122 evt_payload->ctx = rsrc_data->ctx;
1123 evt_payload->core_index = rsrc_data->common_data->core_index;
1124 evt_payload->evt_id = evt_id;
1125
1126 for (i = 0; i < th_payload->num_registers; i++)
1127 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1128
1129 th_payload->evt_payload_priv = evt_payload;
1130
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001131 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001132 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001133}
1134
1135static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1136 void *evt_payload_priv)
1137{
1138 int rc = CAM_VFE_IRQ_STATUS_ERR;
1139 struct cam_isp_resource_node *wm_res = wm_node;
1140 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001141 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1142 (wm_res == NULL) ? NULL : wm_res->res_priv;
1143 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001144 uint32_t status_reg;
1145
Harsh Shah23557ae2017-05-13 18:14:34 -07001146 if (!evt_payload || !rsrc_data)
1147 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001148
Harsh Shah23557ae2017-05-13 18:14:34 -07001149 cam_ife_irq_regs = evt_payload->irq_reg_val;
1150 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1151
1152 if (status_reg & BIT(rsrc_data->index)) {
1153 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1154 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001155 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001156 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001157 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001158
1159 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001160 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001161 &evt_payload);
1162
1163 return rc;
1164}
1165
1166static int cam_vfe_bus_init_wm_resource(uint32_t index,
1167 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1168 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1169 struct cam_isp_resource_node *wm_res)
1170{
Harsh Shaha1af8822017-05-11 22:06:36 -07001171 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1172
1173 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1174 GFP_KERNEL);
1175 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001176 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001177 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001178 }
1179 wm_res->res_priv = rsrc_data;
1180
1181 rsrc_data->index = index;
1182 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1183 rsrc_data->common_data = &ver2_bus_priv->common_data;
1184
1185 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1186 INIT_LIST_HEAD(&wm_res->list);
1187
1188 wm_res->start = cam_vfe_bus_start_wm;
1189 wm_res->stop = cam_vfe_bus_stop_wm;
1190 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1191 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1192 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1193
Harsh Shah545df9a2017-06-16 16:43:17 -07001194 return 0;
1195}
1196
1197static int cam_vfe_bus_deinit_wm_resource(
1198 struct cam_isp_resource_node *wm_res)
1199{
1200 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1201
1202 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1203 INIT_LIST_HEAD(&wm_res->list);
1204
1205 wm_res->start = NULL;
1206 wm_res->stop = NULL;
1207 wm_res->top_half_handler = NULL;
1208 wm_res->bottom_half_handler = NULL;
1209 wm_res->hw_intf = NULL;
1210
1211 rsrc_data = wm_res->res_priv;
1212 wm_res->res_priv = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001213 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07001214 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07001215 kfree(rsrc_data);
1216
1217 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001218}
1219
1220static void cam_vfe_bus_add_wm_to_comp_grp(
1221 struct cam_isp_resource_node *comp_grp,
1222 uint32_t composite_mask)
1223{
1224 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1225
1226 rsrc_data->composite_mask |= composite_mask;
1227}
1228
1229static void cam_vfe_bus_match_comp_grp(
1230 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1231 struct cam_isp_resource_node **comp_grp,
1232 uint32_t comp_grp_local_idx,
1233 uint32_t unique_id)
1234{
1235 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1236 struct cam_isp_resource_node *comp_grp_local = NULL;
1237
1238 list_for_each_entry(comp_grp_local,
1239 &ver2_bus_priv->used_comp_grp, list) {
1240 rsrc_data = comp_grp_local->res_priv;
1241 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1242 rsrc_data->unique_id == unique_id) {
1243 /* Match found */
1244 *comp_grp = comp_grp_local;
1245 return;
1246 }
1247 }
1248
1249 *comp_grp = NULL;
1250}
1251
1252static int cam_vfe_bus_acquire_comp_grp(
1253 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1254 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001255 void *tasklet,
1256 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001257 uint32_t unique_id,
1258 uint32_t is_dual,
1259 uint32_t is_master,
1260 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1261 struct cam_isp_resource_node **comp_grp)
1262{
1263 int rc = 0;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001264 uint32_t bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001265 struct cam_isp_resource_node *comp_grp_local = NULL;
1266 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1267
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001268 bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
1269 out_port_info->comp_grp_id);
1270 /* Perform match only if there is valid comp grp request */
1271 if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
1272 /* Check if matching comp_grp already acquired */
1273 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1274 bus_comp_grp_id, unique_id);
1275 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001276
1277 if (!comp_grp_local) {
1278 /* First find a free group */
1279 if (is_dual) {
1280 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001281 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001282 return -ENODEV;
1283 }
1284 comp_grp_local = list_first_entry(
1285 &ver2_bus_priv->free_dual_comp_grp,
1286 struct cam_isp_resource_node, list);
1287 rsrc_data = comp_grp_local->res_priv;
1288 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1289 dual_slave_core,
1290 comp_grp_local->hw_intf->hw_idx,
1291 &rsrc_data->intra_client_mask);
1292 } else {
1293 if (list_empty(&ver2_bus_priv->free_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_comp_grp,
1299 struct cam_isp_resource_node, list);
1300 rsrc_data = comp_grp_local->res_priv;
1301 }
1302
1303 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001304 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001305 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1306
1307 rsrc_data->is_master = is_master;
1308 rsrc_data->composite_mask = 0;
1309 rsrc_data->unique_id = unique_id;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001310 rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001311
1312 list_add_tail(&comp_grp_local->list,
1313 &ver2_bus_priv->used_comp_grp);
1314
1315 } else {
1316 rsrc_data = comp_grp_local->res_priv;
1317 /* Do not support runtime change in composite mask */
1318 if (comp_grp_local->res_state ==
1319 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001320 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001321 comp_grp_local->res_state,
1322 rsrc_data->comp_grp_type);
1323 return -EBUSY;
1324 }
1325 }
1326
Harsh Shah19f55812017-06-26 18:58:49 -07001327 rsrc_data->ctx = ctx;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001328 rsrc_data->acquire_dev_cnt++;
Harsh Shaha1af8822017-05-11 22:06:36 -07001329 *comp_grp = comp_grp_local;
1330
1331 return rc;
1332}
1333
1334static int cam_vfe_bus_release_comp_grp(
1335 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1336 struct cam_isp_resource_node *in_comp_grp)
1337{
1338 struct cam_isp_resource_node *comp_grp = NULL;
1339 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1340 int match_found = 0;
1341
1342 if (!in_comp_grp) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001343 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
Harsh Shaha1af8822017-05-11 22:06:36 -07001344 return -EINVAL;
1345 }
1346
1347 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001348 CAM_ERR(CAM_ISP, "Already released Comp Grp");
Harsh Shaha1af8822017-05-11 22:06:36 -07001349 return 0;
1350 }
1351
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001352 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
1353 CAM_ERR(CAM_ISP, "Invalid State %d",
1354 in_comp_grp->res_state);
1355 return -EBUSY;
1356 }
1357
Harsh Shaha1af8822017-05-11 22:06:36 -07001358 in_rsrc_data = in_comp_grp->res_priv;
1359
1360 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1361 if (comp_grp == in_comp_grp) {
1362 match_found = 1;
1363 break;
1364 }
1365 }
1366
1367 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001368 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001369 in_rsrc_data->comp_grp_type);
1370 return -ENODEV;
1371 }
1372
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001373 in_rsrc_data->acquire_dev_cnt--;
1374 if (in_rsrc_data->acquire_dev_cnt == 0) {
1375 list_del(&comp_grp->list);
Harsh Shaha1af8822017-05-11 22:06:36 -07001376
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001377 in_rsrc_data->unique_id = 0;
1378 in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
1379 in_rsrc_data->composite_mask = 0;
1380 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
Harsh Shaha1af8822017-05-11 22:06:36 -07001381
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001382 comp_grp->tasklet_info = NULL;
1383 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
Harsh Shaha1af8822017-05-11 22:06:36 -07001384
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001385 if (in_rsrc_data->comp_grp_type >=
1386 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1387 in_rsrc_data->comp_grp_type <=
1388 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1389 list_add_tail(&comp_grp->list,
1390 &ver2_bus_priv->free_dual_comp_grp);
1391 else if (in_rsrc_data->comp_grp_type >=
1392 CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1393 in_rsrc_data->comp_grp_type <=
1394 CAM_VFE_BUS_VER2_COMP_GRP_5)
1395 list_add_tail(&comp_grp->list,
1396 &ver2_bus_priv->free_comp_grp);
1397 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001398
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001399 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001400}
1401
1402static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1403{
1404 int rc = 0;
1405 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1406 comp_grp->res_priv;
1407 struct cam_vfe_bus_ver2_common_data *common_data =
1408 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001409 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001410
1411 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1412 rsrc_data->hw_regs->comp_mask);
1413
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001414 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1415 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1416 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001417
1418 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1419 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1420 rsrc_data->is_master) {
1421 int dual_comp_grp = (rsrc_data->comp_grp_type -
1422 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1423 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1424 common_data->common_reg->dual_master_comp_cfg);
1425
1426 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1427 intra_client_en |=
1428 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1429
1430 cam_io_w_mb(intra_client_en, common_data->mem_base +
1431 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001432
1433 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1434 } else {
1435 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1436 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1437 (1 << (rsrc_data->comp_grp_type + 5));
1438 }
1439
1440 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001441 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001442 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1443 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1444 bus_irq_reg_mask, comp_grp,
1445 comp_grp->top_half_handler,
1446 cam_ife_mgr_do_tasklet_buf_done,
1447 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1448 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001449 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001450 rsrc_data->comp_grp_type);
1451 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001452 }
1453
1454 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001455
Harsh Shaha1af8822017-05-11 22:06:36 -07001456 return rc;
1457}
1458
1459static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1460{
1461 int rc = 0;
1462 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1463 comp_grp->res_priv;
1464 struct cam_vfe_bus_ver2_common_data *common_data =
1465 rsrc_data->common_data;
1466
1467 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001468 rc = cam_irq_controller_unsubscribe_irq(
1469 common_data->bus_irq_controller,
1470 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001471
1472 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1473 rsrc_data->hw_regs->comp_mask);
1474 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1475 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1476 rsrc_data->is_master) {
1477 int dual_comp_grp = (rsrc_data->comp_grp_type -
1478 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1479 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1480 common_data->common_reg->dual_master_comp_cfg);
1481
1482 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1483 intra_client_en &=
1484 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1485
1486 cam_io_w_mb(intra_client_en, common_data->mem_base +
1487 common_data->common_reg->dual_master_comp_cfg);
1488 }
1489
1490 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1491
1492 return rc;
1493}
1494
1495static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1496 struct cam_irq_th_payload *th_payload)
1497{
Harsh Shah19f55812017-06-26 18:58:49 -07001498 int32_t rc;
1499 int i;
1500 struct cam_isp_resource_node *comp_grp = NULL;
1501 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1502 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1503
1504 comp_grp = th_payload->handler_priv;
1505 if (!comp_grp) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001506 CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001507 return -ENODEV;
1508 }
1509
1510 rsrc_data = comp_grp->res_priv;
1511
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001512 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1513 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001514
1515 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1516 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001517 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001518 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001519 return rc;
1520 }
1521
1522 cam_isp_hw_get_timestamp(&evt_payload->ts);
1523
1524 evt_payload->ctx = rsrc_data->ctx;
1525 evt_payload->core_index = rsrc_data->common_data->core_index;
1526 evt_payload->evt_id = evt_id;
1527
1528 for (i = 0; i < th_payload->num_registers; i++)
1529 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1530
1531 th_payload->evt_payload_priv = evt_payload;
1532
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001533 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001534 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001535}
1536
1537static int cam_vfe_bus_handle_comp_done_bottom_half(
1538 void *handler_priv,
1539 void *evt_payload_priv)
1540{
1541 int rc = CAM_VFE_IRQ_STATUS_ERR;
1542 struct cam_isp_resource_node *comp_grp = handler_priv;
1543 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1544 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001545 uint32_t *cam_ife_irq_regs;
1546 uint32_t status_reg;
1547 uint32_t comp_err_reg;
1548 uint32_t comp_grp_id;
1549
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001550 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001551
Harsh Shah23557ae2017-05-13 18:14:34 -07001552 if (!evt_payload)
1553 return rc;
1554
1555 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001556
Harsh Shaha1af8822017-05-11 22:06:36 -07001557 switch (rsrc_data->comp_grp_type) {
1558 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1559 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1560 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1561 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1562 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1563 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001564 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001565 CAM_VFE_BUS_VER2_COMP_GRP_0);
1566
1567 /* Check for Regular composite error */
1568 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1569
1570 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1571 if ((status_reg & BIT(11)) &&
1572 (comp_err_reg & rsrc_data->composite_mask)) {
1573 /* Check for Regular composite error */
1574 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1575 break;
1576 }
1577
1578 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1579 /* Check for Regular composite Overwrite */
1580 if ((status_reg & BIT(12)) &&
1581 (comp_err_reg & rsrc_data->composite_mask)) {
1582 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1583 break;
1584 }
1585
Harsh Shah23557ae2017-05-13 18:14:34 -07001586 /* Regular Composite SUCCESS */
1587 if (status_reg & BIT(comp_grp_id + 5)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001588 rsrc_data->irq_trigger_cnt++;
1589 if (rsrc_data->irq_trigger_cnt ==
1590 rsrc_data->acquire_dev_cnt) {
1591 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1592 ~BIT(comp_grp_id + 5);
1593 rsrc_data->irq_trigger_cnt = 0;
1594 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001595 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001596 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001597
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001598 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001599 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001600 break;
1601
1602 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1603 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1604 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1605 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1606 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1607 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001608 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001609 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1610
1611 /* Check for DUAL composite error */
1612 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1613
1614 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1615 if ((status_reg & BIT(6)) &&
1616 (comp_err_reg & rsrc_data->composite_mask)) {
1617 /* Check for DUAL composite error */
1618 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1619 break;
1620 }
1621
1622 /* Check for Dual composite Overwrite */
1623 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1624 if ((status_reg & BIT(7)) &&
1625 (comp_err_reg & rsrc_data->composite_mask)) {
1626 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1627 break;
1628 }
1629
Harsh Shah23557ae2017-05-13 18:14:34 -07001630 /* DUAL Composite SUCCESS */
1631 if (status_reg & BIT(comp_grp_id)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001632 rsrc_data->irq_trigger_cnt++;
1633 if (rsrc_data->irq_trigger_cnt ==
1634 rsrc_data->acquire_dev_cnt) {
1635 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1636 ~BIT(comp_grp_id + 5);
1637 rsrc_data->irq_trigger_cnt = 0;
1638 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001639 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001640 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001641
1642 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001643 default:
1644 rc = CAM_VFE_IRQ_STATUS_ERR;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001645 CAM_ERR(CAM_ISP, "Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001646 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001647 break;
1648 }
1649
1650 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001651 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001652 &evt_payload);
1653
1654 return rc;
1655}
1656
1657static int cam_vfe_bus_init_comp_grp(uint32_t index,
1658 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1659 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1660 struct cam_isp_resource_node *comp_grp)
1661{
Harsh Shah545df9a2017-06-16 16:43:17 -07001662 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001663
1664 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1665 GFP_KERNEL);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001666 if (!rsrc_data)
Harsh Shaha1af8822017-05-11 22:06:36 -07001667 return -ENOMEM;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001668
Harsh Shaha1af8822017-05-11 22:06:36 -07001669 comp_grp->res_priv = rsrc_data;
1670
1671 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1672 INIT_LIST_HEAD(&comp_grp->list);
1673
1674 rsrc_data->comp_grp_type = index;
1675 rsrc_data->common_data = &ver2_bus_priv->common_data;
1676 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1677 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1678
Harsh Shaha1af8822017-05-11 22:06:36 -07001679 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1680 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1681 list_add_tail(&comp_grp->list,
1682 &ver2_bus_priv->free_dual_comp_grp);
1683 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1684 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1685 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1686
1687 comp_grp->start = cam_vfe_bus_start_comp_grp;
1688 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1689 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1690 comp_grp->bottom_half_handler =
1691 cam_vfe_bus_handle_comp_done_bottom_half;
1692 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1693
1694 return 0;
1695}
1696
Harsh Shah545df9a2017-06-16 16:43:17 -07001697static int cam_vfe_bus_deinit_comp_grp(
1698 struct cam_isp_resource_node *comp_grp)
1699{
1700 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1701 comp_grp->res_priv;
1702
1703 comp_grp->start = NULL;
1704 comp_grp->stop = NULL;
1705 comp_grp->top_half_handler = NULL;
1706 comp_grp->bottom_half_handler = NULL;
1707 comp_grp->hw_intf = NULL;
1708
1709 list_del_init(&comp_grp->list);
1710 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1711
1712 comp_grp->res_priv = NULL;
1713
1714 if (!rsrc_data) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001715 CAM_ERR(CAM_ISP, "comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001716 return -ENODEV;
1717 }
1718 kfree(rsrc_data);
1719
1720 return 0;
1721}
1722
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001723static int cam_vfe_bus_get_secure_mode(void *priv, void *cmd_args,
1724 uint32_t arg_size)
1725{
1726 bool *mode = cmd_args;
1727 struct cam_isp_resource_node *res =
1728 (struct cam_isp_resource_node *) priv;
1729 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data =
1730 (struct cam_vfe_bus_ver2_vfe_out_data *)res->res_priv;
1731
1732 *mode =
1733 (rsrc_data->secure_mode == CAM_SECURE_MODE_SECURE) ?
1734 true : false;
1735
1736 return 0;
1737}
1738
Harsh Shah19f55812017-06-26 18:58:49 -07001739static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1740 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001741{
1742 int rc = -ENODEV;
1743 int i;
1744 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1745 uint32_t format;
Harsh Shahea526f82017-09-25 14:47:32 -07001746 int num_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07001747 uint32_t subscribe_irq;
1748 uint32_t client_done_mask;
1749 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1750 struct cam_vfe_acquire_args *acq_args = acquire_args;
1751 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1752 struct cam_isp_resource_node *rsrc_node = NULL;
1753 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001754 uint32_t secure_caps = 0, mode;
Harsh Shaha1af8822017-05-11 22:06:36 -07001755
1756 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001757 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001758 return -EINVAL;
1759 }
1760
1761 out_acquire_args = &acq_args->vfe_out;
1762 format = out_acquire_args->out_port_info->format;
1763
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001764 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001765 out_acquire_args->out_port_info->res_type);
1766
1767 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1768 out_acquire_args->out_port_info->res_type);
1769 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1770 return -ENODEV;
1771
1772 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1773 if (num_wm < 1)
1774 return -EINVAL;
1775
1776 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1777 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001778 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001779 vfe_out_res_id, rsrc_node->res_state);
1780 return -EBUSY;
1781 }
1782
1783 rsrc_data = rsrc_node->res_priv;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001784 secure_caps = cam_vfe_bus_can_be_secure(
1785 rsrc_data->out_type);
1786 mode = out_acquire_args->out_port_info->secure_mode;
1787 mutex_lock(&rsrc_data->common_data->bus_mutex);
1788 if (secure_caps) {
1789 if (!rsrc_data->common_data->num_sec_out) {
1790 rsrc_data->secure_mode = mode;
1791 rsrc_data->common_data->secure_mode = mode;
1792 } else {
1793 if (mode == rsrc_data->common_data->secure_mode) {
1794 rsrc_data->secure_mode =
1795 rsrc_data->common_data->secure_mode;
1796 } else {
1797 rc = -EINVAL;
1798 CAM_ERR_RATE_LIMIT(CAM_ISP,
1799 "Mismatch: Acquire mode[%d], drvr mode[%d]",
1800 rsrc_data->common_data->secure_mode,
1801 mode);
1802 mutex_unlock(
1803 &rsrc_data->common_data->bus_mutex);
1804 return -EINVAL;
1805 }
1806 }
1807 rsrc_data->common_data->num_sec_out++;
1808 }
1809 mutex_unlock(&rsrc_data->common_data->bus_mutex);
1810
Harsh Shaha1af8822017-05-11 22:06:36 -07001811 rsrc_data->num_wm = num_wm;
1812 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1813 rsrc_node->tasklet_info = acq_args->tasklet;
1814 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1815 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1816
1817 /* Reserve Composite Group */
1818 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1819 CAM_ISP_RES_COMP_GROUP_NONE &&
1820 out_acquire_args->out_port_info->comp_grp_id <
1821 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1822 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1823 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001824 acq_args->tasklet,
1825 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001826 out_acquire_args->unique_id,
1827 out_acquire_args->is_dual,
1828 out_acquire_args->is_master,
1829 out_acquire_args->dual_slave_core,
1830 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001831 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001832 CAM_ERR(CAM_ISP,
1833 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001834 rsrc_data->common_data->core_index,
1835 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001836 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001837 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001838
1839 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001840 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001841 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001842 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001843
1844 /* Reserve WM */
1845 for (i = 0; i < num_wm; i++) {
1846 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1847 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001848 acq_args->tasklet,
1849 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001850 vfe_out_res_id,
1851 i,
1852 out_acquire_args->split_id,
1853 subscribe_irq,
1854 &rsrc_data->wm_res[i],
1855 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001856 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001857 CAM_ERR(CAM_ISP,
1858 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001859 rsrc_data->common_data->core_index,
1860 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001861 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001862 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001863
1864 if (rsrc_data->comp_grp)
1865 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1866 client_done_mask);
1867 }
1868
1869 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1870 out_acquire_args->rsrc_node = rsrc_node;
1871
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001872 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001873 return rc;
1874
1875release_wm:
1876 for (i--; i >= 0; i--)
1877 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1878
1879 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1880 rsrc_data->comp_grp);
1881
1882 return rc;
1883}
1884
Harsh Shah19f55812017-06-26 18:58:49 -07001885static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1886 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001887{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001888 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001889 struct cam_isp_resource_node *vfe_out = NULL;
1890 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001891 uint32_t secure_caps = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001892
1893 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001894 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001895 bus_priv, release_args);
1896 return -EINVAL;
1897 }
1898
1899 vfe_out = release_args;
1900 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001901
Harsh Shaha1af8822017-05-11 22:06:36 -07001902 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001903 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001904 vfe_out->res_state);
1905 }
1906
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001907 for (i = 0; i < rsrc_data->num_wm; i++)
1908 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1909 rsrc_data->num_wm = 0;
1910
1911 if (rsrc_data->comp_grp)
1912 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1913 rsrc_data->comp_grp = NULL;
1914
1915 vfe_out->tasklet_info = NULL;
1916 vfe_out->cdm_ops = NULL;
1917 rsrc_data->cdm_util_ops = NULL;
1918
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001919 secure_caps = cam_vfe_bus_can_be_secure(rsrc_data->out_type);
1920 mutex_lock(&rsrc_data->common_data->bus_mutex);
1921 if (secure_caps) {
1922 if (rsrc_data->secure_mode ==
1923 rsrc_data->common_data->secure_mode) {
1924 rsrc_data->common_data->num_sec_out--;
1925 rsrc_data->secure_mode =
1926 CAM_SECURE_MODE_NON_SECURE;
1927 } else {
1928 /*
1929 * The validity of the mode is properly
1930 * checked while acquiring the output port.
1931 * not expected to reach here, unless there is
1932 * some corruption.
1933 */
1934 CAM_ERR(CAM_ISP, "driver[%d],resource[%d] mismatch",
1935 rsrc_data->common_data->secure_mode,
1936 rsrc_data->secure_mode);
1937 }
1938
1939 if (!rsrc_data->common_data->num_sec_out)
1940 rsrc_data->common_data->secure_mode =
1941 CAM_SECURE_MODE_NON_SECURE;
1942 }
1943 mutex_unlock(&rsrc_data->common_data->bus_mutex);
1944
Harsh Shaha1af8822017-05-11 22:06:36 -07001945 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1946 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1947
1948 return 0;
1949}
1950
Harsh Shah19f55812017-06-26 18:58:49 -07001951static int cam_vfe_bus_start_vfe_out(
1952 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001953{
1954 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001955 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1956 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1957
1958 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001959 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001960 return -EINVAL;
1961 }
1962
1963 rsrc_data = vfe_out->res_priv;
1964 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001965
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001966 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001967
1968 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001969 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001970 vfe_out->res_state);
1971 return -EACCES;
1972 }
1973
1974 for (i = 0; i < rsrc_data->num_wm; i++)
1975 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1976
1977 if (rsrc_data->comp_grp)
1978 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1979
Harsh Shaha1af8822017-05-11 22:06:36 -07001980 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1981 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1982 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1983 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1984 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1985 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001986 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1987 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1988 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1989 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1990 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1991 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1992 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1993 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1994 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1995
Harsh Shah23557ae2017-05-13 18:14:34 -07001996 /* no clock gating at bus input */
1997 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
1998
1999 /* BUS_WR_TEST_BUS_CTRL */
2000 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
2001
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05302002 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07002003 return rc;
2004}
2005
Harsh Shah19f55812017-06-26 18:58:49 -07002006static int cam_vfe_bus_stop_vfe_out(
2007 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07002008{
2009 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07002010 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2011
2012 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002013 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07002014 return -EINVAL;
2015 }
2016
2017 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002018
2019 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
2020 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
2021 return rc;
2022 }
2023
2024 if (rsrc_data->comp_grp)
2025 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
2026
2027 for (i = 0; i < rsrc_data->num_wm; i++)
2028 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
2029
Harsh Shaha1af8822017-05-11 22:06:36 -07002030
2031 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
2032 return rc;
2033}
2034
2035static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
2036 struct cam_irq_th_payload *th_payload)
2037{
2038 return -EPERM;
2039}
2040
2041static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
2042 void *handler_priv,
2043 void *evt_payload_priv)
2044{
2045 int rc = -EINVAL;
2046 struct cam_isp_resource_node *vfe_out = handler_priv;
2047 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2048
2049 /*
2050 * If this resource has Composite Group then we only handle
2051 * Composite done. We acquire Composite if number of WM > 1.
2052 * So Else case is only one individual buf_done = WM[0].
2053 */
2054 if (rsrc_data->comp_grp) {
2055 rc = rsrc_data->comp_grp->bottom_half_handler(
2056 rsrc_data->comp_grp, evt_payload_priv);
2057 } else {
2058 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07002059 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07002060 }
2061
2062 return rc;
2063}
2064
2065static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
2066 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
2067 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
2068 struct cam_isp_resource_node *vfe_out)
2069{
2070 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2071 int rc = 0;
2072
2073 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
2074 GFP_KERNEL);
2075 if (!rsrc_data) {
Harsh Shaha1af8822017-05-11 22:06:36 -07002076 rc = -ENOMEM;
2077 return rc;
2078 }
2079 vfe_out->res_priv = rsrc_data;
2080
2081 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
2082 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2083 INIT_LIST_HEAD(&vfe_out->list);
2084
2085 rsrc_data->out_type = index;
2086 rsrc_data->common_data = &ver2_bus_priv->common_data;
2087 rsrc_data->max_width =
2088 ver2_hw_info->vfe_out_hw_info[index].max_width;
2089 rsrc_data->max_height =
2090 ver2_hw_info->vfe_out_hw_info[index].max_height;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002091 rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shaha1af8822017-05-11 22:06:36 -07002092
2093 vfe_out->start = cam_vfe_bus_start_vfe_out;
2094 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
2095 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
2096 vfe_out->bottom_half_handler =
2097 cam_vfe_bus_handle_vfe_out_done_bottom_half;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002098 vfe_out->process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002099 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
2100
2101 return 0;
2102}
2103
Harsh Shah545df9a2017-06-16 16:43:17 -07002104static int cam_vfe_bus_deinit_vfe_out_resource(
2105 struct cam_isp_resource_node *vfe_out)
2106{
2107 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2108
2109 vfe_out->start = NULL;
2110 vfe_out->stop = NULL;
2111 vfe_out->top_half_handler = NULL;
2112 vfe_out->bottom_half_handler = NULL;
2113 vfe_out->hw_intf = NULL;
2114
2115 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
2116 INIT_LIST_HEAD(&vfe_out->list);
2117 vfe_out->res_priv = NULL;
2118
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002119 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07002120 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002121 kfree(rsrc_data);
2122
2123 return 0;
2124}
2125
Harsh Shaha1af8822017-05-11 22:06:36 -07002126static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
2127 struct cam_irq_th_payload *th_payload)
2128{
Harsh Shaha1af8822017-05-11 22:06:36 -07002129 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002130
Harsh Shah19f55812017-06-26 18:58:49 -07002131 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002132 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07002133 return cam_irq_controller_handle_irq(evt_id,
2134 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07002135}
2136
2137static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
2138 uint32_t arg_size)
2139{
2140 struct cam_vfe_bus_ver2_priv *bus_priv;
2141 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002142 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07002143 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2144 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002145 uint32_t *reg_val_pair;
2146 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07002147 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07002148
2149 /*
2150 * Need the entire buf io config so we can get the stride info
2151 * for the wm.
2152 */
2153
2154 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2155 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
2156
2157 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2158 update_buf->cdm.res->res_priv;
2159
2160 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002161 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07002162 return -EINVAL;
2163 }
2164
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002165 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002166 CAM_ERR(CAM_ISP,
2167 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002168 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07002169 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07002170 }
2171
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002172 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2173 io_cfg = update_buf->io_cfg;
2174
2175 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07002176 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002177 CAM_ERR(CAM_ISP,
2178 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07002179 j, MAX_REG_VAL_PAIR_SIZE);
2180 return -ENOMEM;
2181 }
2182
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002183 wm_data = vfe_out_data->wm_res[i]->res_priv;
2184
2185 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302186 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
2187 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002188 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2189 wm_data->hw_regs->stride,
2190 io_cfg->planes[i].plane_stride);
2191 wm_data->stride = io_cfg->planes[i].plane_stride;
2192 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002193 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002194
2195 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002196 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002197 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2198 wm_data->hw_regs->framedrop_pattern,
2199 io_cfg->framedrop_pattern);
2200 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
2201 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002202 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2203 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002204
2205 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002206 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002207 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2208 wm_data->hw_regs->framedrop_period,
2209 io_cfg->framedrop_period);
2210 wm_data->framedrop_period = io_cfg->framedrop_period;
2211 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002212 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2213 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002214
2215 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002216 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002217 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2218 wm_data->hw_regs->irq_subsample_period,
2219 io_cfg->subsample_period);
2220 wm_data->irq_subsample_period =
2221 io_cfg->subsample_period;
2222 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002223 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002224 wm_data->irq_subsample_period);
2225
2226 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002227 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002228 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2229 wm_data->hw_regs->irq_subsample_pattern,
2230 io_cfg->subsample_pattern);
2231 wm_data->irq_subsample_pattern =
2232 io_cfg->subsample_pattern;
2233 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002234 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002235 wm_data->irq_subsample_pattern);
2236
2237 if (wm_data->en_ubwc) {
2238 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002239 CAM_ERR(CAM_ISP,
2240 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002241 return -EINVAL;
2242 }
2243 if (wm_data->packer_cfg !=
2244 io_cfg->planes[i].packer_config ||
2245 !wm_data->init_cfg_done) {
2246 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2247 wm_data->hw_regs->packer_cfg,
2248 io_cfg->planes[i].packer_config);
2249 wm_data->packer_cfg =
2250 io_cfg->planes[i].packer_config;
2251 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002252 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2253 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002254
2255 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
2256 || !wm_data->init_cfg_done) {
2257 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2258 wm_data->hw_regs->ubwc_regs->tile_cfg,
2259 io_cfg->planes[i].tile_config);
2260 wm_data->tile_cfg =
2261 io_cfg->planes[i].tile_config;
2262 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002263 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002264
2265 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2266 !wm_data->init_cfg_done) {
2267 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2268 wm_data->hw_regs->ubwc_regs->h_init,
2269 io_cfg->planes[i].h_init);
2270 wm_data->h_init = io_cfg->planes[i].h_init;
2271 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002272 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002273
2274 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2275 !wm_data->init_cfg_done) {
2276 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2277 wm_data->hw_regs->ubwc_regs->v_init,
2278 io_cfg->planes[i].v_init);
2279 wm_data->v_init = io_cfg->planes[i].v_init;
2280 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002281 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002282
2283 if (wm_data->ubwc_meta_stride !=
2284 io_cfg->planes[i].meta_stride ||
2285 !wm_data->init_cfg_done) {
2286 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2287 wm_data->hw_regs->ubwc_regs->
2288 meta_stride,
2289 io_cfg->planes[i].meta_stride);
2290 wm_data->ubwc_meta_stride =
2291 io_cfg->planes[i].meta_stride;
2292 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002293 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2294 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002295
2296 if (wm_data->ubwc_mode_cfg !=
2297 io_cfg->planes[i].mode_config ||
2298 !wm_data->init_cfg_done) {
2299 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2300 wm_data->hw_regs->ubwc_regs->mode_cfg,
2301 io_cfg->planes[i].mode_config);
2302 wm_data->ubwc_mode_cfg =
2303 io_cfg->planes[i].mode_config;
2304 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002305 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2306 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002307
2308 if (wm_data->ubwc_meta_offset !=
2309 io_cfg->planes[i].meta_offset ||
2310 !wm_data->init_cfg_done) {
2311 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2312 wm_data->hw_regs->ubwc_regs->
2313 meta_offset,
2314 io_cfg->planes[i].meta_offset);
2315 wm_data->ubwc_meta_offset =
2316 io_cfg->planes[i].meta_offset;
2317 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002318 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002319 wm_data->ubwc_meta_offset);
2320
2321 /* UBWC meta address */
2322 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2323 wm_data->hw_regs->ubwc_regs->meta_addr,
2324 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002325 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002326 update_buf->image_buf[i]);
2327 }
2328
2329 /* WM Image address */
2330 if (wm_data->en_ubwc)
2331 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2332 wm_data->hw_regs->image_addr,
2333 (update_buf->image_buf[i] +
2334 io_cfg->planes[i].meta_size));
2335 else
2336 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2337 wm_data->hw_regs->image_addr,
2338 update_buf->image_buf[i]);
2339
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002340 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002341
Junzhe Zou193d78c2017-05-16 15:10:54 -07002342 frame_inc = io_cfg->planes[i].plane_stride *
2343 io_cfg->planes[i].slice_height;
2344 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2345 wm_data->hw_regs->frame_inc, frame_inc);
2346
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002347 /* enable the WM */
2348 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2349 wm_data->hw_regs->cfg,
2350 wm_data->en_cfg);
2351
2352 /* set initial configuration done */
2353 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002354 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002355 }
2356
2357 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002358
2359 /* cdm util returns dwords, need to convert to bytes */
2360 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002361 CAM_ERR(CAM_ISP,
2362 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002363 update_buf->cdm.size, size);
2364 return -ENOMEM;
2365 }
2366
Harsh Shaha1af8822017-05-11 22:06:36 -07002367 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002368 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2369
Harsh Shaha1af8822017-05-11 22:06:36 -07002370 /* cdm util returns dwords, need to convert to bytes */
2371 update_buf->cdm.used_bytes = size * 4;
2372
2373 return 0;
2374}
2375
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002376static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2377 uint32_t arg_size)
2378{
2379 struct cam_vfe_bus_ver2_priv *bus_priv;
2380 struct cam_isp_hw_get_hfr_update *update_hfr;
2381 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2382 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2383 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2384 uint32_t *reg_val_pair;
2385 uint32_t i, j, size = 0;
2386
2387 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2388 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2389
2390 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2391 update_hfr->cdm.res->res_priv;
2392
2393 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2394 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2395 return -EINVAL;
2396 }
2397
2398 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2399 hfr_cfg = update_hfr->io_hfr_cfg;
2400
2401 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2402 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2403 CAM_ERR(CAM_ISP,
2404 "reg_val_pair %d exceeds the array limit %lu",
2405 j, MAX_REG_VAL_PAIR_SIZE);
2406 return -ENOMEM;
2407 }
2408
2409 wm_data = vfe_out_data->wm_res[i]->res_priv;
2410
2411 if ((wm_data->framedrop_pattern !=
2412 hfr_cfg->framedrop_pattern) ||
2413 !wm_data->hfr_cfg_done) {
2414 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2415 wm_data->hw_regs->framedrop_pattern,
2416 hfr_cfg->framedrop_pattern);
2417 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2418 }
2419 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2420 wm_data->framedrop_pattern);
2421
2422 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2423 !wm_data->hfr_cfg_done) {
2424 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2425 wm_data->hw_regs->framedrop_period,
2426 hfr_cfg->framedrop_period);
2427 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2428 }
2429 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2430 wm_data->framedrop_period);
2431
2432 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2433 || !wm_data->hfr_cfg_done) {
2434 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2435 wm_data->hw_regs->irq_subsample_period,
2436 hfr_cfg->subsample_period);
2437 wm_data->irq_subsample_period =
2438 hfr_cfg->subsample_period;
2439 }
2440 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2441 wm_data->irq_subsample_period);
2442
2443 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2444 || !wm_data->hfr_cfg_done) {
2445 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2446 wm_data->hw_regs->irq_subsample_pattern,
2447 hfr_cfg->subsample_pattern);
2448 wm_data->irq_subsample_pattern =
2449 hfr_cfg->subsample_pattern;
2450 }
2451 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2452 wm_data->irq_subsample_pattern);
2453
2454 /* set initial configuration done */
2455 if (!wm_data->hfr_cfg_done)
2456 wm_data->hfr_cfg_done = true;
2457 }
2458
2459 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2460
2461 /* cdm util returns dwords, need to convert to bytes */
2462 if ((size * 4) > update_hfr->cdm.size) {
2463 CAM_ERR(CAM_ISP,
2464 "Failed! Buf size:%d insufficient, expected size:%d",
2465 update_hfr->cdm.size, size);
2466 return -ENOMEM;
2467 }
2468
2469 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2470 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2471
2472 /* cdm util returns dwords, need to convert to bytes */
2473 update_hfr->cdm.used_bytes = size * 4;
2474
2475 return 0;
2476}
2477
Harsh Shah19f55812017-06-26 18:58:49 -07002478static int cam_vfe_bus_start_hw(void *hw_priv,
2479 void *start_hw_args, uint32_t arg_size)
2480{
2481 return cam_vfe_bus_start_vfe_out(hw_priv);
2482}
2483
2484static int cam_vfe_bus_stop_hw(void *hw_priv,
2485 void *stop_hw_args, uint32_t arg_size)
2486{
2487 return cam_vfe_bus_stop_vfe_out(hw_priv);
2488}
2489
2490static int cam_vfe_bus_init_hw(void *hw_priv,
2491 void *init_hw_args, uint32_t arg_size)
2492{
2493 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2494 uint32_t top_irq_reg_mask[2] = {0};
2495
2496 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002497 CAM_ERR(CAM_ISP, "Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002498 return -EINVAL;
2499 }
2500
2501 top_irq_reg_mask[0] = (1 << 9);
2502
2503 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2504 bus_priv->common_data.vfe_irq_controller,
2505 CAM_IRQ_PRIORITY_2,
2506 top_irq_reg_mask,
2507 bus_priv,
2508 cam_vfe_bus_ver2_handle_irq,
2509 NULL,
2510 NULL,
2511 NULL);
2512
2513 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002514 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002515 return -EFAULT;
2516 }
2517
2518 return 0;
2519}
2520
2521static int cam_vfe_bus_deinit_hw(void *hw_priv,
2522 void *deinit_hw_args, uint32_t arg_size)
2523{
2524 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2525 int rc;
2526
2527 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002528 CAM_ERR(CAM_ISP, "Error: Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002529 return -EINVAL;
2530 }
2531
2532 rc = cam_irq_controller_unsubscribe_irq(
2533 bus_priv->common_data.vfe_irq_controller,
2534 bus_priv->irq_handle);
2535 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002536 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002537
2538 return rc;
2539}
2540
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002541static int __cam_vfe_bus_process_cmd(void *priv,
2542 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2543{
2544 return cam_vfe_bus_process_cmd(priv, cmd_type, cmd_args, arg_size);
2545}
2546
2547static int cam_vfe_bus_process_cmd(
2548 struct cam_isp_resource_node *priv,
Harsh Shaha1af8822017-05-11 22:06:36 -07002549 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2550{
2551 int rc = -EINVAL;
2552
2553 if (!priv || !cmd_args) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002554 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
Harsh Shaha1af8822017-05-11 22:06:36 -07002555 return -EINVAL;
2556 }
2557
2558 switch (cmd_type) {
2559 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2560 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2561 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002562 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2563 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2564 break;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002565 case CAM_VFE_HW_CMD_GET_SECURE_MODE:
2566 rc = cam_vfe_bus_get_secure_mode(priv, cmd_args, arg_size);
2567 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002568 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002569 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002570 cmd_type);
2571 break;
2572 }
2573
2574 return rc;
2575}
2576
2577int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002578 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002579 struct cam_hw_intf *hw_intf,
2580 void *bus_hw_info,
2581 void *vfe_irq_controller,
2582 struct cam_vfe_bus **vfe_bus)
2583{
2584 int i, rc = 0;
2585 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2586 struct cam_vfe_bus *vfe_bus_local;
2587 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2588
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002589 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002590
Harsh Shah19f55812017-06-26 18:58:49 -07002591 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002592 CAM_ERR(CAM_ISP,
2593 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2594 soc_info, hw_intf, bus_hw_info);
2595 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002596 rc = -EINVAL;
2597 goto end;
2598 }
2599
Harsh Shaha1af8822017-05-11 22:06:36 -07002600 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2601 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002602 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002603 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002604 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002605 }
2606
2607 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2608 GFP_KERNEL);
2609 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002610 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002611 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002612 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002613 }
2614 vfe_bus_local->bus_priv = bus_priv;
2615
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002616 bus_priv->common_data.num_sec_out = 0;
2617 bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shah19f55812017-06-26 18:58:49 -07002618 bus_priv->common_data.core_index = soc_info->index;
2619 bus_priv->common_data.mem_base =
2620 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002621 bus_priv->common_data.hw_intf = hw_intf;
2622 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2623 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002624 mutex_init(&bus_priv->common_data.bus_mutex);
Harsh Shaha1af8822017-05-11 22:06:36 -07002625
Harsh Shah19f55812017-06-26 18:58:49 -07002626 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2627 &ver2_hw_info->common_reg.irq_reg_info,
2628 &bus_priv->common_data.bus_irq_controller);
2629 if (rc) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002630 CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002631 goto free_bus_priv;
2632 }
2633
Harsh Shaha1af8822017-05-11 22:06:36 -07002634 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2635 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2636 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2637
2638 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2639 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2640 &bus_priv->bus_client[i]);
2641 if (rc < 0) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002642 CAM_ERR(CAM_ISP, "Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002643 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002644 }
2645 }
2646
2647 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2648 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2649 &bus_priv->comp_grp[i]);
2650 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002651 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002652 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002653 }
2654 }
2655
2656 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2657 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2658 &bus_priv->vfe_out[i]);
2659 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002660 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002661 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002662 }
2663 }
2664
Harsh Shah19f55812017-06-26 18:58:49 -07002665 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2666 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2667 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2668 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2669 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002670 }
2671
Harsh Shah19f55812017-06-26 18:58:49 -07002672 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2673 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2674 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2675 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2676 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2677 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2678 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002679 vfe_bus_local->bottom_half_handler = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002680 vfe_bus_local->hw_ops.process_cmd = __cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002681
2682 *vfe_bus = vfe_bus_local;
2683
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002684 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002685 return rc;
2686
Harsh Shah545df9a2017-06-16 16:43:17 -07002687deinit_vfe_out:
2688 if (i < 0)
2689 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2690 for (--i; i >= 0; i--)
2691 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2692
2693deinit_comp_grp:
2694 if (i < 0)
2695 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2696 for (--i; i >= 0; i--)
2697 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2698
2699deinit_wm:
2700 if (i < 0)
2701 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2702 for (--i; i >= 0; i--)
2703 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2704
Harsh Shah19f55812017-06-26 18:58:49 -07002705free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002706 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002707
2708free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002709 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002710
2711end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002712 return rc;
2713}
Harsh Shah545df9a2017-06-16 16:43:17 -07002714
2715int cam_vfe_bus_ver2_deinit(
2716 struct cam_vfe_bus **vfe_bus)
2717{
2718 int i, rc = 0;
2719 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2720 struct cam_vfe_bus *vfe_bus_local;
2721
2722 if (!vfe_bus || !*vfe_bus) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002723 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002724 return -EINVAL;
2725 }
2726 vfe_bus_local = *vfe_bus;
2727
2728 bus_priv = vfe_bus_local->bus_priv;
2729 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002730 CAM_ERR(CAM_ISP, "bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002731 rc = -ENODEV;
2732 goto free_bus_local;
2733 }
2734
Harsh Shah19f55812017-06-26 18:58:49 -07002735 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2736 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2737 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002738
2739 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2740 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2741 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002742 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002743 "Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002744 }
2745
2746 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2747 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2748 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002749 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002750 "Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002751 }
2752
2753 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2754 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2755 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002756 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002757 "Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002758 }
2759
2760 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2761 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2762 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2763
Harsh Shah19f55812017-06-26 18:58:49 -07002764 rc = cam_irq_controller_deinit(
2765 &bus_priv->common_data.bus_irq_controller);
2766 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002767 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002768 "Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002769
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002770 mutex_destroy(&bus_priv->common_data.bus_mutex);
Harsh Shah545df9a2017-06-16 16:43:17 -07002771 kfree(vfe_bus_local->bus_priv);
2772
2773free_bus_local:
2774 kfree(vfe_bus_local);
2775
2776 *vfe_bus = NULL;
2777
2778 return rc;
2779}
2780