blob: 7aa5b9d0f1c17f24f91e3f5ee40989072648af62 [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:
818 rsrc_data->width = CAM_VFE_RDI_BUS_DEFAULT_WIDTH;
819 rsrc_data->height = 0;
820 rsrc_data->stride = CAM_VFE_RDI_BUS_DEFAULT_STRIDE;
821 rsrc_data->pack_fmt = 0x0;
822 rsrc_data->en_cfg = 0x3;
823 break;
824 case CAM_FORMAT_PLAIN8:
825 rsrc_data->en_cfg = 0x1;
826 rsrc_data->pack_fmt = 0x1;
827 rsrc_data->width = rsrc_data->width * 2;
828 rsrc_data->stride = rsrc_data->width;
829 break;
830 case CAM_FORMAT_PLAIN16_10:
831 rsrc_data->en_cfg = 0x1;
832 rsrc_data->pack_fmt = 0x2;
833 rsrc_data->width = rsrc_data->width * 2;
834 rsrc_data->stride = rsrc_data->width;
835 break;
836 case CAM_FORMAT_PLAIN16_12:
837 rsrc_data->en_cfg = 0x1;
838 rsrc_data->pack_fmt = 0x3;
839 rsrc_data->width = rsrc_data->width * 2;
840 rsrc_data->stride = rsrc_data->width;
841 break;
842 case CAM_FORMAT_PLAIN16_14:
843 rsrc_data->en_cfg = 0x1;
844 rsrc_data->pack_fmt = 0x4;
845 rsrc_data->width = rsrc_data->width * 2;
846 rsrc_data->stride = rsrc_data->width;
847 break;
848 case CAM_FORMAT_PLAIN16_16:
849 rsrc_data->en_cfg = 0x1;
850 rsrc_data->pack_fmt = 0x5;
851 rsrc_data->width = rsrc_data->width * 2;
852 rsrc_data->stride = rsrc_data->width;
853 break;
854 case CAM_FORMAT_PLAIN32_20:
855 rsrc_data->en_cfg = 0x1;
856 rsrc_data->pack_fmt = 0x9;
857 break;
858 case CAM_FORMAT_PLAIN64:
859 rsrc_data->en_cfg = 0x1;
860 rsrc_data->pack_fmt = 0xA;
861 break;
862 case CAM_FORMAT_PLAIN128:
863 rsrc_data->en_cfg = 0x1;
864 rsrc_data->pack_fmt = 0x0;
865 break;
866 default:
867 CAM_ERR(CAM_ISP, "Unsupported RDI format %d",
868 rsrc_data->format);
869 return -EINVAL;
870 }
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530871 } else if (rsrc_data->index < 5 ||
872 rsrc_data->index == 7 || rsrc_data->index == 8) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700873 /* Write master 3, 4 - for Full OUT , 7-8 FD OUT */
874 switch (rsrc_data->format) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700875 case CAM_FORMAT_UBWC_NV12_4R:
876 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700877 rsrc_data->width = ALIGNUP(rsrc_data->width, 64);
878 switch (plane) {
879 case PLANE_C:
880 rsrc_data->height /= 2;
881 break;
882 case PLANE_Y:
883 break;
884 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700885 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700886 return -EINVAL;
887 }
888 break;
889 case CAM_FORMAT_UBWC_NV12:
890 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700891 /* Fall through for NV12 */
892 case CAM_FORMAT_NV21:
893 case CAM_FORMAT_NV12:
894 switch (plane) {
895 case PLANE_C:
896 rsrc_data->height /= 2;
897 break;
898 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700899 break;
900 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700901 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700902 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700903 }
904 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700905 case CAM_FORMAT_UBWC_TP10:
906 rsrc_data->en_ubwc = 1;
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700907 rsrc_data->width =
908 ALIGNUP(rsrc_data->width, 48) * 4 / 3;
909 switch (plane) {
910 case PLANE_C:
911 rsrc_data->height /= 2;
912 break;
913 case PLANE_Y:
914 break;
915 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700916 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700917 return -EINVAL;
918 }
919 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700920 case CAM_FORMAT_TP10:
Krishnankutty Kolathappilly06406e52017-08-17 00:50:21 -0700921 rsrc_data->width =
922 ALIGNUP(rsrc_data->width, 3) * 4 / 3;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700923 switch (plane) {
924 case PLANE_C:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700925 rsrc_data->height /= 2;
926 break;
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700927 case PLANE_Y:
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700928 break;
929 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700930 CAM_ERR(CAM_ISP, "Invalid plane %d", plane);
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700931 return -EINVAL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700932 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700933 break;
934 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -0700935 CAM_ERR(CAM_ISP, "Invalid format %d",
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700936 rsrc_data->format);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700937 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700938 }
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700939 rsrc_data->en_cfg = 0x1;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530940 } else if (rsrc_data->index >= 11) {
Krishnankutty Kolathappillyf39e6412017-07-18 15:58:22 -0700941 /* Write master 11-19 stats */
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530942 rsrc_data->width = 0;
943 rsrc_data->height = 0;
Abhishek Kondaveetib31b46c2017-06-23 04:56:24 +0530944 rsrc_data->stride = 1;
945 rsrc_data->en_cfg = 0x3;
Shilpa Mamidi169ddf02017-09-15 18:05:59 +0530946 } else if (rsrc_data->index == 9) {
947 /* Write master 9 - Raw dump */
948 rsrc_data->width = rsrc_data->width * 2;
949 rsrc_data->stride = rsrc_data->width;
950 rsrc_data->en_cfg = 0x1;
951 } else {
952 /* Write master 5-6 DS ports, 10 PDAF */
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700953 rsrc_data->width = rsrc_data->width * 4;
954 rsrc_data->height = rsrc_data->height / 2;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700955 rsrc_data->en_cfg = 0x1;
Harsh Shaha1af8822017-05-11 22:06:36 -0700956 }
Harsh Shaha1af8822017-05-11 22:06:36 -0700957
958 *client_done_mask = (1 << wm_idx);
959 *wm_res = wm_res_local;
960
961 return 0;
962}
963
964static int cam_vfe_bus_release_wm(void *bus_priv,
965 struct cam_isp_resource_node *wm_res)
966{
967 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
968 wm_res->res_priv;
969
970 rsrc_data->irq_enabled = 0;
971 rsrc_data->offset = 0;
972 rsrc_data->width = 0;
973 rsrc_data->height = 0;
974 rsrc_data->stride = 0;
975 rsrc_data->format = 0;
976 rsrc_data->pack_fmt = 0;
977 rsrc_data->burst_len = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -0700978 rsrc_data->irq_subsample_period = 0;
979 rsrc_data->irq_subsample_pattern = 0;
980 rsrc_data->framedrop_period = 0;
981 rsrc_data->framedrop_pattern = 0;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700982 rsrc_data->packer_cfg = 0;
983 rsrc_data->en_ubwc = 0;
984 rsrc_data->tile_cfg = 0;
985 rsrc_data->h_init = 0;
986 rsrc_data->v_init = 0;
987 rsrc_data->ubwc_meta_stride = 0;
988 rsrc_data->ubwc_mode_cfg = 0;
989 rsrc_data->ubwc_meta_offset = 0;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -0700990 rsrc_data->init_cfg_done = false;
991 rsrc_data->hfr_cfg_done = false;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -0700992 rsrc_data->en_cfg = 0;
Harsh Shah19f55812017-06-26 18:58:49 -0700993
994 wm_res->tasklet_info = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -0700995 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
996
997 return 0;
998}
999
1000static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
1001{
1002 int rc = 0;
1003 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1004 wm_res->res_priv;
1005 struct cam_vfe_bus_ver2_common_data *common_data =
1006 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001007 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001008
Harsh Shah23557ae2017-05-13 18:14:34 -07001009 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_addr);
1010 cam_io_w_mb(0, common_data->mem_base + rsrc_data->hw_regs->header_cfg);
Harsh Shah23557ae2017-05-13 18:14:34 -07001011 cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->burst_limit);
1012
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001013 cam_io_w_mb(rsrc_data->width,
Harsh Shaha1af8822017-05-11 22:06:36 -07001014 common_data->mem_base + rsrc_data->hw_regs->buffer_width_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001015 cam_io_w(rsrc_data->height,
Harsh Shaha1af8822017-05-11 22:06:36 -07001016 common_data->mem_base + rsrc_data->hw_regs->buffer_height_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001017 cam_io_w(rsrc_data->pack_fmt,
Harsh Shaha1af8822017-05-11 22:06:36 -07001018 common_data->mem_base + rsrc_data->hw_regs->packer_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001019
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05301020 /* Configure stride for RDIs */
1021 if (rsrc_data->index < 3)
1022 cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
1023 rsrc_data->hw_regs->stride));
Harsh Shaha1af8822017-05-11 22:06:36 -07001024
Harsh Shah19f55812017-06-26 18:58:49 -07001025 /* Subscribe IRQ */
1026 if (rsrc_data->irq_enabled) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001027 CAM_DBG(CAM_ISP, "Subscribe WM%d IRQ", rsrc_data->index);
Harsh Shah19f55812017-06-26 18:58:49 -07001028 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG1] =
1029 (1 << rsrc_data->index);
1030 wm_res->irq_handle = cam_irq_controller_subscribe_irq(
1031 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1032 bus_irq_reg_mask, wm_res,
1033 wm_res->top_half_handler,
1034 cam_ife_mgr_do_tasklet_buf_done,
1035 wm_res->tasklet_info, cam_tasklet_enqueue_cmd);
1036 if (wm_res->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001037 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for WM %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001038 rsrc_data->index);
1039 return -EFAULT;
1040 }
1041 }
1042
Junzhe Zou3d292562017-07-12 17:59:58 -07001043 /* enable ubwc if needed*/
1044 if (rsrc_data->en_ubwc) {
1045 cam_io_w_mb(0x1, common_data->mem_base +
1046 rsrc_data->hw_regs->ubwc_regs->mode_cfg);
1047 }
1048
Harsh Shah19f55812017-06-26 18:58:49 -07001049 /* Enable WM */
1050 cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
1051 rsrc_data->hw_regs->cfg);
1052
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001053 CAM_DBG(CAM_ISP, "WM res %d width = %d, height = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001054 rsrc_data->width, rsrc_data->height);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001055 CAM_DBG(CAM_ISP, "WM res %d pk_fmt = %d", rsrc_data->index,
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001056 rsrc_data->pack_fmt & PACKER_FMT_MAX);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001057 CAM_DBG(CAM_ISP, "WM res %d stride = %d, burst len = %d",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07001058 rsrc_data->index, rsrc_data->stride, 0xf);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001059 CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
1060 rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
1061 rsrc_data->en_cfg);
Harsh Shaha1af8822017-05-11 22:06:36 -07001062
1063 wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
1064
1065 return rc;
1066}
1067
1068static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
1069{
1070 int rc = 0;
1071 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1072 wm_res->res_priv;
1073 struct cam_vfe_bus_ver2_common_data *common_data =
1074 rsrc_data->common_data;
1075
1076 /* Disble WM */
1077 cam_io_w_mb(0x0,
1078 common_data->mem_base + rsrc_data->hw_regs->cfg);
1079
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001080 CAM_DBG(CAM_ISP, "irq_enabled %d", rsrc_data->irq_enabled);
Harsh Shaha1af8822017-05-11 22:06:36 -07001081 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001082 if (rsrc_data->irq_enabled)
1083 rc = cam_irq_controller_unsubscribe_irq(
1084 common_data->bus_irq_controller,
1085 wm_res->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001086
1087 /* Halt & Reset WM */
1088 cam_io_w_mb(BIT(rsrc_data->index),
1089 common_data->mem_base + common_data->common_reg->sw_reset);
1090
1091 wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1092
1093 return rc;
1094}
1095
1096static int cam_vfe_bus_handle_wm_done_top_half(uint32_t evt_id,
1097 struct cam_irq_th_payload *th_payload)
1098{
Harsh Shah19f55812017-06-26 18:58:49 -07001099 int32_t rc;
1100 int i;
1101 struct cam_isp_resource_node *wm_res = NULL;
1102 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data = NULL;
1103 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1104
1105 wm_res = th_payload->handler_priv;
1106 if (!wm_res) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001107 CAM_ERR_RATE_LIMIT(CAM_ISP, "Error: No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001108 return -ENODEV;
1109 }
1110
1111 rsrc_data = wm_res->res_priv;
1112
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001113 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1114 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001115
1116 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1117 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001118 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001119 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001120 return rc;
1121 }
1122
1123 cam_isp_hw_get_timestamp(&evt_payload->ts);
1124
1125 evt_payload->ctx = rsrc_data->ctx;
1126 evt_payload->core_index = rsrc_data->common_data->core_index;
1127 evt_payload->evt_id = evt_id;
1128
1129 for (i = 0; i < th_payload->num_registers; i++)
1130 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1131
1132 th_payload->evt_payload_priv = evt_payload;
1133
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001134 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001135 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001136}
1137
1138static int cam_vfe_bus_handle_wm_done_bottom_half(void *wm_node,
1139 void *evt_payload_priv)
1140{
1141 int rc = CAM_VFE_IRQ_STATUS_ERR;
1142 struct cam_isp_resource_node *wm_res = wm_node;
1143 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001144 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data =
1145 (wm_res == NULL) ? NULL : wm_res->res_priv;
1146 uint32_t *cam_ife_irq_regs;
Harsh Shaha1af8822017-05-11 22:06:36 -07001147 uint32_t status_reg;
1148
Harsh Shah23557ae2017-05-13 18:14:34 -07001149 if (!evt_payload || !rsrc_data)
1150 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001151
Harsh Shah23557ae2017-05-13 18:14:34 -07001152 cam_ife_irq_regs = evt_payload->irq_reg_val;
1153 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1];
1154
1155 if (status_reg & BIT(rsrc_data->index)) {
1156 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS1] &=
1157 ~BIT(rsrc_data->index);
Harsh Shaha1af8822017-05-11 22:06:36 -07001158 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001159 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001160 CAM_DBG(CAM_ISP, "status_reg %x rc %d", status_reg, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001161
1162 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001163 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001164 &evt_payload);
1165
1166 return rc;
1167}
1168
1169static int cam_vfe_bus_init_wm_resource(uint32_t index,
1170 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1171 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1172 struct cam_isp_resource_node *wm_res)
1173{
Harsh Shaha1af8822017-05-11 22:06:36 -07001174 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1175
1176 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_wm_resource_data),
1177 GFP_KERNEL);
1178 if (!rsrc_data) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001179 CAM_DBG(CAM_ISP, "Failed to alloc for WM res priv");
Harsh Shah545df9a2017-06-16 16:43:17 -07001180 return -ENOMEM;
Harsh Shaha1af8822017-05-11 22:06:36 -07001181 }
1182 wm_res->res_priv = rsrc_data;
1183
1184 rsrc_data->index = index;
1185 rsrc_data->hw_regs = &ver2_hw_info->bus_client_reg[index];
1186 rsrc_data->common_data = &ver2_bus_priv->common_data;
1187
1188 wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1189 INIT_LIST_HEAD(&wm_res->list);
1190
1191 wm_res->start = cam_vfe_bus_start_wm;
1192 wm_res->stop = cam_vfe_bus_stop_wm;
1193 wm_res->top_half_handler = cam_vfe_bus_handle_wm_done_top_half;
1194 wm_res->bottom_half_handler = cam_vfe_bus_handle_wm_done_bottom_half;
1195 wm_res->hw_intf = ver2_bus_priv->common_data.hw_intf;
1196
Harsh Shah545df9a2017-06-16 16:43:17 -07001197 return 0;
1198}
1199
1200static int cam_vfe_bus_deinit_wm_resource(
1201 struct cam_isp_resource_node *wm_res)
1202{
1203 struct cam_vfe_bus_ver2_wm_resource_data *rsrc_data;
1204
1205 wm_res->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1206 INIT_LIST_HEAD(&wm_res->list);
1207
1208 wm_res->start = NULL;
1209 wm_res->stop = NULL;
1210 wm_res->top_half_handler = NULL;
1211 wm_res->bottom_half_handler = NULL;
1212 wm_res->hw_intf = NULL;
1213
1214 rsrc_data = wm_res->res_priv;
1215 wm_res->res_priv = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001216 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07001217 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07001218 kfree(rsrc_data);
1219
1220 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001221}
1222
1223static void cam_vfe_bus_add_wm_to_comp_grp(
1224 struct cam_isp_resource_node *comp_grp,
1225 uint32_t composite_mask)
1226{
1227 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
1228
1229 rsrc_data->composite_mask |= composite_mask;
1230}
1231
1232static void cam_vfe_bus_match_comp_grp(
1233 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1234 struct cam_isp_resource_node **comp_grp,
1235 uint32_t comp_grp_local_idx,
1236 uint32_t unique_id)
1237{
1238 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1239 struct cam_isp_resource_node *comp_grp_local = NULL;
1240
1241 list_for_each_entry(comp_grp_local,
1242 &ver2_bus_priv->used_comp_grp, list) {
1243 rsrc_data = comp_grp_local->res_priv;
1244 if (rsrc_data->comp_grp_local_idx == comp_grp_local_idx &&
1245 rsrc_data->unique_id == unique_id) {
1246 /* Match found */
1247 *comp_grp = comp_grp_local;
1248 return;
1249 }
1250 }
1251
1252 *comp_grp = NULL;
1253}
1254
1255static int cam_vfe_bus_acquire_comp_grp(
1256 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1257 struct cam_isp_out_port_info *out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001258 void *tasklet,
1259 void *ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001260 uint32_t unique_id,
1261 uint32_t is_dual,
1262 uint32_t is_master,
1263 enum cam_vfe_bus_ver2_vfe_core_id dual_slave_core,
1264 struct cam_isp_resource_node **comp_grp)
1265{
1266 int rc = 0;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001267 uint32_t bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001268 struct cam_isp_resource_node *comp_grp_local = NULL;
1269 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1270
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001271 bus_comp_grp_id = cam_vfe_bus_comp_grp_id_convert(
1272 out_port_info->comp_grp_id);
1273 /* Perform match only if there is valid comp grp request */
1274 if (out_port_info->comp_grp_id != CAM_ISP_RES_COMP_GROUP_NONE) {
1275 /* Check if matching comp_grp already acquired */
1276 cam_vfe_bus_match_comp_grp(ver2_bus_priv, &comp_grp_local,
1277 bus_comp_grp_id, unique_id);
1278 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001279
1280 if (!comp_grp_local) {
1281 /* First find a free group */
1282 if (is_dual) {
1283 if (list_empty(&ver2_bus_priv->free_dual_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001284 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001285 return -ENODEV;
1286 }
1287 comp_grp_local = list_first_entry(
1288 &ver2_bus_priv->free_dual_comp_grp,
1289 struct cam_isp_resource_node, list);
1290 rsrc_data = comp_grp_local->res_priv;
1291 rc = cam_vfe_bus_ver2_get_intra_client_mask(
1292 dual_slave_core,
1293 comp_grp_local->hw_intf->hw_idx,
1294 &rsrc_data->intra_client_mask);
1295 } else {
1296 if (list_empty(&ver2_bus_priv->free_comp_grp)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001297 CAM_ERR(CAM_ISP, "No Free Composite Group");
Harsh Shaha1af8822017-05-11 22:06:36 -07001298 return -ENODEV;
1299 }
1300 comp_grp_local = list_first_entry(
1301 &ver2_bus_priv->free_comp_grp,
1302 struct cam_isp_resource_node, list);
1303 rsrc_data = comp_grp_local->res_priv;
1304 }
1305
1306 list_del(&comp_grp_local->list);
Harsh Shah19f55812017-06-26 18:58:49 -07001307 comp_grp_local->tasklet_info = tasklet;
Harsh Shaha1af8822017-05-11 22:06:36 -07001308 comp_grp_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1309
1310 rsrc_data->is_master = is_master;
1311 rsrc_data->composite_mask = 0;
1312 rsrc_data->unique_id = unique_id;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001313 rsrc_data->comp_grp_local_idx = bus_comp_grp_id;
Harsh Shaha1af8822017-05-11 22:06:36 -07001314
1315 list_add_tail(&comp_grp_local->list,
1316 &ver2_bus_priv->used_comp_grp);
1317
1318 } else {
1319 rsrc_data = comp_grp_local->res_priv;
1320 /* Do not support runtime change in composite mask */
1321 if (comp_grp_local->res_state ==
1322 CAM_ISP_RESOURCE_STATE_STREAMING) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001323 CAM_ERR(CAM_ISP, "Invalid State %d Comp Grp %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001324 comp_grp_local->res_state,
1325 rsrc_data->comp_grp_type);
1326 return -EBUSY;
1327 }
1328 }
1329
Harsh Shah19f55812017-06-26 18:58:49 -07001330 rsrc_data->ctx = ctx;
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001331 rsrc_data->acquire_dev_cnt++;
Harsh Shaha1af8822017-05-11 22:06:36 -07001332 *comp_grp = comp_grp_local;
1333
1334 return rc;
1335}
1336
1337static int cam_vfe_bus_release_comp_grp(
1338 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1339 struct cam_isp_resource_node *in_comp_grp)
1340{
1341 struct cam_isp_resource_node *comp_grp = NULL;
1342 struct cam_vfe_bus_ver2_comp_grp_data *in_rsrc_data = NULL;
1343 int match_found = 0;
1344
1345 if (!in_comp_grp) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001346 CAM_ERR(CAM_ISP, "Invalid Params Comp Grp %pK", in_comp_grp);
Harsh Shaha1af8822017-05-11 22:06:36 -07001347 return -EINVAL;
1348 }
1349
1350 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001351 CAM_ERR(CAM_ISP, "Already released Comp Grp");
Harsh Shaha1af8822017-05-11 22:06:36 -07001352 return 0;
1353 }
1354
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001355 if (in_comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) {
1356 CAM_ERR(CAM_ISP, "Invalid State %d",
1357 in_comp_grp->res_state);
1358 return -EBUSY;
1359 }
1360
Harsh Shaha1af8822017-05-11 22:06:36 -07001361 in_rsrc_data = in_comp_grp->res_priv;
1362
1363 list_for_each_entry(comp_grp, &ver2_bus_priv->used_comp_grp, list) {
1364 if (comp_grp == in_comp_grp) {
1365 match_found = 1;
1366 break;
1367 }
1368 }
1369
1370 if (!match_found) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001371 CAM_ERR(CAM_ISP, "Could not find matching Comp Grp type %u",
Harsh Shaha1af8822017-05-11 22:06:36 -07001372 in_rsrc_data->comp_grp_type);
1373 return -ENODEV;
1374 }
1375
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001376 in_rsrc_data->acquire_dev_cnt--;
1377 if (in_rsrc_data->acquire_dev_cnt == 0) {
1378 list_del(&comp_grp->list);
Harsh Shaha1af8822017-05-11 22:06:36 -07001379
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001380 in_rsrc_data->unique_id = 0;
1381 in_rsrc_data->comp_grp_local_idx = CAM_VFE_BUS_COMP_GROUP_NONE;
1382 in_rsrc_data->composite_mask = 0;
1383 in_rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
Harsh Shaha1af8822017-05-11 22:06:36 -07001384
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001385 comp_grp->tasklet_info = NULL;
1386 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
Harsh Shaha1af8822017-05-11 22:06:36 -07001387
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001388 if (in_rsrc_data->comp_grp_type >=
1389 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1390 in_rsrc_data->comp_grp_type <=
1391 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1392 list_add_tail(&comp_grp->list,
1393 &ver2_bus_priv->free_dual_comp_grp);
1394 else if (in_rsrc_data->comp_grp_type >=
1395 CAM_VFE_BUS_VER2_COMP_GRP_0 &&
1396 in_rsrc_data->comp_grp_type <=
1397 CAM_VFE_BUS_VER2_COMP_GRP_5)
1398 list_add_tail(&comp_grp->list,
1399 &ver2_bus_priv->free_comp_grp);
1400 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001401
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001402 return 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07001403}
1404
1405static int cam_vfe_bus_start_comp_grp(struct cam_isp_resource_node *comp_grp)
1406{
1407 int rc = 0;
1408 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1409 comp_grp->res_priv;
1410 struct cam_vfe_bus_ver2_common_data *common_data =
1411 rsrc_data->common_data;
Harsh Shah19f55812017-06-26 18:58:49 -07001412 uint32_t bus_irq_reg_mask[CAM_VFE_BUS_IRQ_MAX] = {0};
Harsh Shaha1af8822017-05-11 22:06:36 -07001413
1414 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1415 rsrc_data->hw_regs->comp_mask);
1416
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001417 CAM_DBG(CAM_ISP, "composite_mask is 0x%x", rsrc_data->composite_mask);
1418 CAM_DBG(CAM_ISP, "composite_mask addr 0x%x",
1419 rsrc_data->hw_regs->comp_mask);
Harsh Shaha1af8822017-05-11 22:06:36 -07001420
1421 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1422 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1423 rsrc_data->is_master) {
1424 int dual_comp_grp = (rsrc_data->comp_grp_type -
1425 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1426 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1427 common_data->common_reg->dual_master_comp_cfg);
1428
1429 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1430 intra_client_en |=
1431 (rsrc_data->intra_client_mask << dual_comp_grp * 2);
1432
1433 cam_io_w_mb(intra_client_en, common_data->mem_base +
1434 common_data->common_reg->dual_master_comp_cfg);
Harsh Shah19f55812017-06-26 18:58:49 -07001435
1436 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG2] = (1 << dual_comp_grp);
1437 } else {
1438 /* IRQ bits for COMP GRP start at 5. So add 5 to the shift */
1439 bus_irq_reg_mask[CAM_VFE_BUS_IRQ_REG0] =
1440 (1 << (rsrc_data->comp_grp_type + 5));
1441 }
1442
1443 /* Subscribe IRQ */
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001444 CAM_DBG(CAM_ISP, "Subscribe COMP_GRP%d IRQ", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001445 comp_grp->irq_handle = cam_irq_controller_subscribe_irq(
1446 common_data->bus_irq_controller, CAM_IRQ_PRIORITY_1,
1447 bus_irq_reg_mask, comp_grp,
1448 comp_grp->top_half_handler,
1449 cam_ife_mgr_do_tasklet_buf_done,
1450 comp_grp->tasklet_info, cam_tasklet_enqueue_cmd);
1451 if (comp_grp->irq_handle < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001452 CAM_ERR(CAM_ISP, "Subscribe IRQ failed for comp_grp %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001453 rsrc_data->comp_grp_type);
1454 return -EFAULT;
Harsh Shaha1af8822017-05-11 22:06:36 -07001455 }
1456
1457 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shah19f55812017-06-26 18:58:49 -07001458
Harsh Shaha1af8822017-05-11 22:06:36 -07001459 return rc;
1460}
1461
1462static int cam_vfe_bus_stop_comp_grp(struct cam_isp_resource_node *comp_grp)
1463{
1464 int rc = 0;
1465 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1466 comp_grp->res_priv;
1467 struct cam_vfe_bus_ver2_common_data *common_data =
1468 rsrc_data->common_data;
1469
1470 /* Unsubscribe IRQ */
Harsh Shah19f55812017-06-26 18:58:49 -07001471 rc = cam_irq_controller_unsubscribe_irq(
1472 common_data->bus_irq_controller,
1473 comp_grp->irq_handle);
Harsh Shaha1af8822017-05-11 22:06:36 -07001474
1475 cam_io_w_mb(rsrc_data->composite_mask, common_data->mem_base +
1476 rsrc_data->hw_regs->comp_mask);
1477 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1478 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5 &&
1479 rsrc_data->is_master) {
1480 int dual_comp_grp = (rsrc_data->comp_grp_type -
1481 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1482 int intra_client_en = cam_io_r_mb(common_data->mem_base +
1483 common_data->common_reg->dual_master_comp_cfg);
1484
1485 /* 2 Bits per comp_grp. Hence left shift by comp_grp * 2 */
1486 intra_client_en &=
1487 ~(rsrc_data->intra_client_mask << dual_comp_grp * 2);
1488
1489 cam_io_w_mb(intra_client_en, common_data->mem_base +
1490 common_data->common_reg->dual_master_comp_cfg);
1491 }
1492
1493 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1494
1495 return rc;
1496}
1497
1498static int cam_vfe_bus_handle_comp_done_top_half(uint32_t evt_id,
1499 struct cam_irq_th_payload *th_payload)
1500{
Harsh Shah19f55812017-06-26 18:58:49 -07001501 int32_t rc;
1502 int i;
1503 struct cam_isp_resource_node *comp_grp = NULL;
1504 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
1505 struct cam_vfe_bus_irq_evt_payload *evt_payload;
1506
1507 comp_grp = th_payload->handler_priv;
1508 if (!comp_grp) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001509 CAM_ERR_RATE_LIMIT(CAM_ISP, "No resource");
Harsh Shah19f55812017-06-26 18:58:49 -07001510 return -ENODEV;
1511 }
1512
1513 rsrc_data = comp_grp->res_priv;
1514
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001515 CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
1516 CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
Harsh Shah19f55812017-06-26 18:58:49 -07001517
1518 rc = cam_vfe_bus_get_evt_payload(rsrc_data->common_data, &evt_payload);
1519 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001520 CAM_ERR_RATE_LIMIT(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001521 "No tasklet_cmd is free in queue");
Harsh Shah19f55812017-06-26 18:58:49 -07001522 return rc;
1523 }
1524
1525 cam_isp_hw_get_timestamp(&evt_payload->ts);
1526
1527 evt_payload->ctx = rsrc_data->ctx;
1528 evt_payload->core_index = rsrc_data->common_data->core_index;
1529 evt_payload->evt_id = evt_id;
1530
1531 for (i = 0; i < th_payload->num_registers; i++)
1532 evt_payload->irq_reg_val[i] = th_payload->evt_status_arr[i];
1533
1534 th_payload->evt_payload_priv = evt_payload;
1535
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001536 CAM_DBG(CAM_ISP, "Exit");
Harsh Shah19f55812017-06-26 18:58:49 -07001537 return rc;
Harsh Shaha1af8822017-05-11 22:06:36 -07001538}
1539
1540static int cam_vfe_bus_handle_comp_done_bottom_half(
1541 void *handler_priv,
1542 void *evt_payload_priv)
1543{
1544 int rc = CAM_VFE_IRQ_STATUS_ERR;
1545 struct cam_isp_resource_node *comp_grp = handler_priv;
1546 struct cam_vfe_bus_irq_evt_payload *evt_payload = evt_payload_priv;
1547 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = comp_grp->res_priv;
Harsh Shah23557ae2017-05-13 18:14:34 -07001548 uint32_t *cam_ife_irq_regs;
1549 uint32_t status_reg;
1550 uint32_t comp_err_reg;
1551 uint32_t comp_grp_id;
1552
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001553 CAM_DBG(CAM_ISP, "comp grp type %d", rsrc_data->comp_grp_type);
Harsh Shah19f55812017-06-26 18:58:49 -07001554
Harsh Shah23557ae2017-05-13 18:14:34 -07001555 if (!evt_payload)
1556 return rc;
1557
1558 cam_ife_irq_regs = evt_payload->irq_reg_val;
Harsh Shaha1af8822017-05-11 22:06:36 -07001559
Harsh Shaha1af8822017-05-11 22:06:36 -07001560 switch (rsrc_data->comp_grp_type) {
1561 case CAM_VFE_BUS_VER2_COMP_GRP_0:
1562 case CAM_VFE_BUS_VER2_COMP_GRP_1:
1563 case CAM_VFE_BUS_VER2_COMP_GRP_2:
1564 case CAM_VFE_BUS_VER2_COMP_GRP_3:
1565 case CAM_VFE_BUS_VER2_COMP_GRP_4:
1566 case CAM_VFE_BUS_VER2_COMP_GRP_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001567 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001568 CAM_VFE_BUS_VER2_COMP_GRP_0);
1569
1570 /* Check for Regular composite error */
1571 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0];
1572
1573 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_ERR];
1574 if ((status_reg & BIT(11)) &&
1575 (comp_err_reg & rsrc_data->composite_mask)) {
1576 /* Check for Regular composite error */
1577 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1578 break;
1579 }
1580
1581 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_COMP_OWRT];
1582 /* Check for Regular composite Overwrite */
1583 if ((status_reg & BIT(12)) &&
1584 (comp_err_reg & rsrc_data->composite_mask)) {
1585 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1586 break;
1587 }
1588
Harsh Shah23557ae2017-05-13 18:14:34 -07001589 /* Regular Composite SUCCESS */
1590 if (status_reg & BIT(comp_grp_id + 5)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001591 rsrc_data->irq_trigger_cnt++;
1592 if (rsrc_data->irq_trigger_cnt ==
1593 rsrc_data->acquire_dev_cnt) {
1594 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS0] &=
1595 ~BIT(comp_grp_id + 5);
1596 rsrc_data->irq_trigger_cnt = 0;
1597 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001598 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001599 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001600
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001601 CAM_DBG(CAM_ISP, "status reg = 0x%x, bit index = %d rc %d",
Harsh Shah19f55812017-06-26 18:58:49 -07001602 status_reg, (comp_grp_id + 5), rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001603 break;
1604
1605 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0:
1606 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_1:
1607 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_2:
1608 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_3:
1609 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_4:
1610 case CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5:
Harsh Shah23557ae2017-05-13 18:14:34 -07001611 comp_grp_id = (rsrc_data->comp_grp_type -
Harsh Shaha1af8822017-05-11 22:06:36 -07001612 CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0);
1613
1614 /* Check for DUAL composite error */
1615 status_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2];
1616
1617 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_ERR];
1618 if ((status_reg & BIT(6)) &&
1619 (comp_err_reg & rsrc_data->composite_mask)) {
1620 /* Check for DUAL composite error */
1621 rc = CAM_VFE_IRQ_STATUS_ERR_COMP;
1622 break;
1623 }
1624
1625 /* Check for Dual composite Overwrite */
1626 comp_err_reg = cam_ife_irq_regs[CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT];
1627 if ((status_reg & BIT(7)) &&
1628 (comp_err_reg & rsrc_data->composite_mask)) {
1629 rc = CAM_VFE_IRQ_STATUS_COMP_OWRT;
1630 break;
1631 }
1632
Harsh Shah23557ae2017-05-13 18:14:34 -07001633 /* DUAL Composite SUCCESS */
1634 if (status_reg & BIT(comp_grp_id)) {
Karthik Anantha Ram01974172017-09-01 10:42:22 -07001635 rsrc_data->irq_trigger_cnt++;
1636 if (rsrc_data->irq_trigger_cnt ==
1637 rsrc_data->acquire_dev_cnt) {
1638 cam_ife_irq_regs[CAM_IFE_IRQ_BUS_REG_STATUS2] &=
1639 ~BIT(comp_grp_id + 5);
1640 rsrc_data->irq_trigger_cnt = 0;
1641 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001642 rc = CAM_VFE_IRQ_STATUS_SUCCESS;
Harsh Shah23557ae2017-05-13 18:14:34 -07001643 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001644
1645 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07001646 default:
1647 rc = CAM_VFE_IRQ_STATUS_ERR;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001648 CAM_ERR(CAM_ISP, "Invalid comp_grp_type %u",
Harsh Shah19f55812017-06-26 18:58:49 -07001649 rsrc_data->comp_grp_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001650 break;
1651 }
1652
1653 if (rc == CAM_VFE_IRQ_STATUS_SUCCESS)
Harsh Shah19f55812017-06-26 18:58:49 -07001654 cam_vfe_bus_put_evt_payload(rsrc_data->common_data,
Harsh Shaha1af8822017-05-11 22:06:36 -07001655 &evt_payload);
1656
1657 return rc;
1658}
1659
1660static int cam_vfe_bus_init_comp_grp(uint32_t index,
1661 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
1662 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
1663 struct cam_isp_resource_node *comp_grp)
1664{
Harsh Shah545df9a2017-06-16 16:43:17 -07001665 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data = NULL;
Harsh Shaha1af8822017-05-11 22:06:36 -07001666
1667 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_comp_grp_data),
1668 GFP_KERNEL);
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001669 if (!rsrc_data)
Harsh Shaha1af8822017-05-11 22:06:36 -07001670 return -ENOMEM;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001671
Harsh Shaha1af8822017-05-11 22:06:36 -07001672 comp_grp->res_priv = rsrc_data;
1673
1674 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1675 INIT_LIST_HEAD(&comp_grp->list);
1676
1677 rsrc_data->comp_grp_type = index;
1678 rsrc_data->common_data = &ver2_bus_priv->common_data;
1679 rsrc_data->hw_regs = &ver2_hw_info->comp_grp_reg[index];
1680 rsrc_data->dual_slave_core = CAM_VFE_BUS_VER2_VFE_CORE_MAX;
1681
Harsh Shaha1af8822017-05-11 22:06:36 -07001682 if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_0 &&
1683 rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_DUAL_5)
1684 list_add_tail(&comp_grp->list,
1685 &ver2_bus_priv->free_dual_comp_grp);
1686 else if (rsrc_data->comp_grp_type >= CAM_VFE_BUS_VER2_COMP_GRP_0
1687 && rsrc_data->comp_grp_type <= CAM_VFE_BUS_VER2_COMP_GRP_5)
1688 list_add_tail(&comp_grp->list, &ver2_bus_priv->free_comp_grp);
1689
1690 comp_grp->start = cam_vfe_bus_start_comp_grp;
1691 comp_grp->stop = cam_vfe_bus_stop_comp_grp;
1692 comp_grp->top_half_handler = cam_vfe_bus_handle_comp_done_top_half;
1693 comp_grp->bottom_half_handler =
1694 cam_vfe_bus_handle_comp_done_bottom_half;
1695 comp_grp->hw_intf = ver2_bus_priv->common_data.hw_intf;
1696
1697 return 0;
1698}
1699
Harsh Shah545df9a2017-06-16 16:43:17 -07001700static int cam_vfe_bus_deinit_comp_grp(
1701 struct cam_isp_resource_node *comp_grp)
1702{
1703 struct cam_vfe_bus_ver2_comp_grp_data *rsrc_data =
1704 comp_grp->res_priv;
1705
1706 comp_grp->start = NULL;
1707 comp_grp->stop = NULL;
1708 comp_grp->top_half_handler = NULL;
1709 comp_grp->bottom_half_handler = NULL;
1710 comp_grp->hw_intf = NULL;
1711
1712 list_del_init(&comp_grp->list);
1713 comp_grp->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
1714
1715 comp_grp->res_priv = NULL;
1716
1717 if (!rsrc_data) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001718 CAM_ERR(CAM_ISP, "comp_grp_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07001719 return -ENODEV;
1720 }
1721 kfree(rsrc_data);
1722
1723 return 0;
1724}
1725
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001726static int cam_vfe_bus_get_secure_mode(void *priv, void *cmd_args,
1727 uint32_t arg_size)
1728{
1729 bool *mode = cmd_args;
1730 struct cam_isp_resource_node *res =
1731 (struct cam_isp_resource_node *) priv;
1732 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data =
1733 (struct cam_vfe_bus_ver2_vfe_out_data *)res->res_priv;
1734
1735 *mode =
1736 (rsrc_data->secure_mode == CAM_SECURE_MODE_SECURE) ?
1737 true : false;
1738
1739 return 0;
1740}
1741
Harsh Shah19f55812017-06-26 18:58:49 -07001742static int cam_vfe_bus_acquire_vfe_out(void *bus_priv, void *acquire_args,
1743 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001744{
1745 int rc = -ENODEV;
1746 int i;
1747 enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id;
1748 uint32_t format;
1749 uint32_t num_wm;
1750 uint32_t subscribe_irq;
1751 uint32_t client_done_mask;
1752 struct cam_vfe_bus_ver2_priv *ver2_bus_priv = bus_priv;
1753 struct cam_vfe_acquire_args *acq_args = acquire_args;
1754 struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args;
1755 struct cam_isp_resource_node *rsrc_node = NULL;
1756 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001757 uint32_t secure_caps = 0, mode;
Harsh Shaha1af8822017-05-11 22:06:36 -07001758
1759 if (!bus_priv || !acquire_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001760 CAM_ERR(CAM_ISP, "Invalid Param");
Harsh Shaha1af8822017-05-11 22:06:36 -07001761 return -EINVAL;
1762 }
1763
1764 out_acquire_args = &acq_args->vfe_out;
1765 format = out_acquire_args->out_port_info->format;
1766
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001767 CAM_DBG(CAM_ISP, "Acquiring resource type 0x%x",
Harsh Shaha1af8822017-05-11 22:06:36 -07001768 out_acquire_args->out_port_info->res_type);
1769
1770 vfe_out_res_id = cam_vfe_bus_get_out_res_id(
1771 out_acquire_args->out_port_info->res_type);
1772 if (vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX)
1773 return -ENODEV;
1774
1775 num_wm = cam_vfe_bus_get_num_wm(vfe_out_res_id, format);
1776 if (num_wm < 1)
1777 return -EINVAL;
1778
1779 rsrc_node = &ver2_bus_priv->vfe_out[vfe_out_res_id];
1780 if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001781 CAM_ERR(CAM_ISP, "Resource not available: Res_id %d state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001782 vfe_out_res_id, rsrc_node->res_state);
1783 return -EBUSY;
1784 }
1785
1786 rsrc_data = rsrc_node->res_priv;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001787 secure_caps = cam_vfe_bus_can_be_secure(
1788 rsrc_data->out_type);
1789 mode = out_acquire_args->out_port_info->secure_mode;
1790 mutex_lock(&rsrc_data->common_data->bus_mutex);
1791 if (secure_caps) {
1792 if (!rsrc_data->common_data->num_sec_out) {
1793 rsrc_data->secure_mode = mode;
1794 rsrc_data->common_data->secure_mode = mode;
1795 } else {
1796 if (mode == rsrc_data->common_data->secure_mode) {
1797 rsrc_data->secure_mode =
1798 rsrc_data->common_data->secure_mode;
1799 } else {
1800 rc = -EINVAL;
1801 CAM_ERR_RATE_LIMIT(CAM_ISP,
1802 "Mismatch: Acquire mode[%d], drvr mode[%d]",
1803 rsrc_data->common_data->secure_mode,
1804 mode);
1805 mutex_unlock(
1806 &rsrc_data->common_data->bus_mutex);
1807 return -EINVAL;
1808 }
1809 }
1810 rsrc_data->common_data->num_sec_out++;
1811 }
1812 mutex_unlock(&rsrc_data->common_data->bus_mutex);
1813
Harsh Shaha1af8822017-05-11 22:06:36 -07001814 rsrc_data->num_wm = num_wm;
1815 rsrc_node->res_id = out_acquire_args->out_port_info->res_type;
1816 rsrc_node->tasklet_info = acq_args->tasklet;
1817 rsrc_node->cdm_ops = out_acquire_args->cdm_ops;
1818 rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops;
1819
1820 /* Reserve Composite Group */
1821 if (num_wm > 1 || (out_acquire_args->out_port_info->comp_grp_id >
1822 CAM_ISP_RES_COMP_GROUP_NONE &&
1823 out_acquire_args->out_port_info->comp_grp_id <
1824 CAM_ISP_RES_COMP_GROUP_ID_MAX)) {
1825 rc = cam_vfe_bus_acquire_comp_grp(ver2_bus_priv,
1826 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001827 acq_args->tasklet,
1828 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001829 out_acquire_args->unique_id,
1830 out_acquire_args->is_dual,
1831 out_acquire_args->is_master,
1832 out_acquire_args->dual_slave_core,
1833 &rsrc_data->comp_grp);
Harsh Shah19f55812017-06-26 18:58:49 -07001834 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001835 CAM_ERR(CAM_ISP,
1836 "VFE%d Comp_Grp acquire fail for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001837 rsrc_data->common_data->core_index,
1838 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001839 return rc;
Harsh Shah19f55812017-06-26 18:58:49 -07001840 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001841
1842 subscribe_irq = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001843 } else {
Harsh Shaha1af8822017-05-11 22:06:36 -07001844 subscribe_irq = 1;
Harsh Shah19f55812017-06-26 18:58:49 -07001845 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001846
1847 /* Reserve WM */
1848 for (i = 0; i < num_wm; i++) {
1849 rc = cam_vfe_bus_acquire_wm(ver2_bus_priv,
1850 out_acquire_args->out_port_info,
Harsh Shah19f55812017-06-26 18:58:49 -07001851 acq_args->tasklet,
1852 out_acquire_args->ctx,
Harsh Shaha1af8822017-05-11 22:06:36 -07001853 vfe_out_res_id,
1854 i,
1855 out_acquire_args->split_id,
1856 subscribe_irq,
1857 &rsrc_data->wm_res[i],
1858 &client_done_mask);
Harsh Shah19f55812017-06-26 18:58:49 -07001859 if (rc) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001860 CAM_ERR(CAM_ISP,
1861 "VFE%d WM acquire failed for Out %d rc=%d",
Harsh Shah19f55812017-06-26 18:58:49 -07001862 rsrc_data->common_data->core_index,
1863 vfe_out_res_id, rc);
Harsh Shaha1af8822017-05-11 22:06:36 -07001864 goto release_wm;
Harsh Shah19f55812017-06-26 18:58:49 -07001865 }
Harsh Shaha1af8822017-05-11 22:06:36 -07001866
1867 if (rsrc_data->comp_grp)
1868 cam_vfe_bus_add_wm_to_comp_grp(rsrc_data->comp_grp,
1869 client_done_mask);
1870 }
1871
1872 rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
1873 out_acquire_args->rsrc_node = rsrc_node;
1874
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001875 CAM_DBG(CAM_ISP, "Acquire successful");
Harsh Shaha1af8822017-05-11 22:06:36 -07001876 return rc;
1877
1878release_wm:
1879 for (i--; i >= 0; i--)
1880 cam_vfe_bus_release_wm(ver2_bus_priv, rsrc_data->wm_res[i]);
1881
1882 cam_vfe_bus_release_comp_grp(ver2_bus_priv,
1883 rsrc_data->comp_grp);
1884
1885 return rc;
1886}
1887
Harsh Shah19f55812017-06-26 18:58:49 -07001888static int cam_vfe_bus_release_vfe_out(void *bus_priv, void *release_args,
1889 uint32_t args_size)
Harsh Shaha1af8822017-05-11 22:06:36 -07001890{
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001891 uint32_t i;
Harsh Shah19f55812017-06-26 18:58:49 -07001892 struct cam_isp_resource_node *vfe_out = NULL;
1893 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001894 uint32_t secure_caps = 0;
Harsh Shah19f55812017-06-26 18:58:49 -07001895
1896 if (!bus_priv || !release_args) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001897 CAM_ERR(CAM_ISP, "Invalid input bus_priv %pK release_args %pK",
Harsh Shah19f55812017-06-26 18:58:49 -07001898 bus_priv, release_args);
1899 return -EINVAL;
1900 }
1901
1902 vfe_out = release_args;
1903 rsrc_data = vfe_out->res_priv;
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001904
Harsh Shaha1af8822017-05-11 22:06:36 -07001905 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001906 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001907 vfe_out->res_state);
1908 }
1909
Jing Zhoue71fd4a2017-05-15 19:44:34 -07001910 for (i = 0; i < rsrc_data->num_wm; i++)
1911 cam_vfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
1912 rsrc_data->num_wm = 0;
1913
1914 if (rsrc_data->comp_grp)
1915 cam_vfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
1916 rsrc_data->comp_grp = NULL;
1917
1918 vfe_out->tasklet_info = NULL;
1919 vfe_out->cdm_ops = NULL;
1920 rsrc_data->cdm_util_ops = NULL;
1921
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001922 secure_caps = cam_vfe_bus_can_be_secure(rsrc_data->out_type);
1923 mutex_lock(&rsrc_data->common_data->bus_mutex);
1924 if (secure_caps) {
1925 if (rsrc_data->secure_mode ==
1926 rsrc_data->common_data->secure_mode) {
1927 rsrc_data->common_data->num_sec_out--;
1928 rsrc_data->secure_mode =
1929 CAM_SECURE_MODE_NON_SECURE;
1930 } else {
1931 /*
1932 * The validity of the mode is properly
1933 * checked while acquiring the output port.
1934 * not expected to reach here, unless there is
1935 * some corruption.
1936 */
1937 CAM_ERR(CAM_ISP, "driver[%d],resource[%d] mismatch",
1938 rsrc_data->common_data->secure_mode,
1939 rsrc_data->secure_mode);
1940 }
1941
1942 if (!rsrc_data->common_data->num_sec_out)
1943 rsrc_data->common_data->secure_mode =
1944 CAM_SECURE_MODE_NON_SECURE;
1945 }
1946 mutex_unlock(&rsrc_data->common_data->bus_mutex);
1947
Harsh Shaha1af8822017-05-11 22:06:36 -07001948 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED)
1949 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
1950
1951 return 0;
1952}
1953
Harsh Shah19f55812017-06-26 18:58:49 -07001954static int cam_vfe_bus_start_vfe_out(
1955 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07001956{
1957 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07001958 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
1959 struct cam_vfe_bus_ver2_common_data *common_data = NULL;
1960
1961 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001962 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07001963 return -EINVAL;
1964 }
1965
1966 rsrc_data = vfe_out->res_priv;
1967 common_data = rsrc_data->common_data;
Harsh Shaha1af8822017-05-11 22:06:36 -07001968
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07001969 CAM_DBG(CAM_ISP, "Start resource index %d", rsrc_data->out_type);
Harsh Shaha1af8822017-05-11 22:06:36 -07001970
1971 if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07001972 CAM_ERR(CAM_ISP, "Invalid resource state:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07001973 vfe_out->res_state);
1974 return -EACCES;
1975 }
1976
1977 for (i = 0; i < rsrc_data->num_wm; i++)
1978 rc = cam_vfe_bus_start_wm(rsrc_data->wm_res[i]);
1979
1980 if (rsrc_data->comp_grp)
1981 rc = cam_vfe_bus_start_comp_grp(rsrc_data->comp_grp);
1982
Harsh Shaha1af8822017-05-11 22:06:36 -07001983 /* BUS_WR_INPUT_IF_ADDR_SYNC_CFG */
1984 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000207C);
1985 /* BUS_WR_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
1986 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002080);
1987 /* BUS_WR_INPUT_IF_ADDR_SYNC_NO_SYNC */
1988 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x00002084);
Harsh Shaha1af8822017-05-11 22:06:36 -07001989 /* BUS_WR_INPUT_IF_ADDR_SYNC_0 */
1990 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002088);
1991 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000208c);
1992 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002090);
1993 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002094);
1994 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x00002098);
1995 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000209c);
1996 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a0);
1997 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x000020a4);
1998
Harsh Shah23557ae2017-05-13 18:14:34 -07001999 /* no clock gating at bus input */
2000 cam_io_w_mb(0xFFFFF, rsrc_data->common_data->mem_base + 0x0000200C);
2001
2002 /* BUS_WR_TEST_BUS_CTRL */
2003 cam_io_w_mb(0x0, rsrc_data->common_data->mem_base + 0x0000211C);
2004
Abhishek Kondaveeti157ae882017-07-08 06:56:48 +05302005 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
Harsh Shaha1af8822017-05-11 22:06:36 -07002006 return rc;
2007}
2008
Harsh Shah19f55812017-06-26 18:58:49 -07002009static int cam_vfe_bus_stop_vfe_out(
2010 struct cam_isp_resource_node *vfe_out)
Harsh Shaha1af8822017-05-11 22:06:36 -07002011{
2012 int rc = 0, i;
Harsh Shah19f55812017-06-26 18:58:49 -07002013 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2014
2015 if (!vfe_out) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002016 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah19f55812017-06-26 18:58:49 -07002017 return -EINVAL;
2018 }
2019
2020 rsrc_data = vfe_out->res_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002021
2022 if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE ||
2023 vfe_out->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
2024 return rc;
2025 }
2026
2027 if (rsrc_data->comp_grp)
2028 rc = cam_vfe_bus_stop_comp_grp(rsrc_data->comp_grp);
2029
2030 for (i = 0; i < rsrc_data->num_wm; i++)
2031 rc = cam_vfe_bus_stop_wm(rsrc_data->wm_res[i]);
2032
Harsh Shaha1af8822017-05-11 22:06:36 -07002033
2034 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
2035 return rc;
2036}
2037
2038static int cam_vfe_bus_handle_vfe_out_done_top_half(uint32_t evt_id,
2039 struct cam_irq_th_payload *th_payload)
2040{
2041 return -EPERM;
2042}
2043
2044static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
2045 void *handler_priv,
2046 void *evt_payload_priv)
2047{
2048 int rc = -EINVAL;
2049 struct cam_isp_resource_node *vfe_out = handler_priv;
2050 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2051
2052 /*
2053 * If this resource has Composite Group then we only handle
2054 * Composite done. We acquire Composite if number of WM > 1.
2055 * So Else case is only one individual buf_done = WM[0].
2056 */
2057 if (rsrc_data->comp_grp) {
2058 rc = rsrc_data->comp_grp->bottom_half_handler(
2059 rsrc_data->comp_grp, evt_payload_priv);
2060 } else {
2061 rc = rsrc_data->wm_res[0]->bottom_half_handler(
Harsh Shah23557ae2017-05-13 18:14:34 -07002062 rsrc_data->wm_res[0], evt_payload_priv);
Harsh Shaha1af8822017-05-11 22:06:36 -07002063 }
2064
2065 return rc;
2066}
2067
2068static int cam_vfe_bus_init_vfe_out_resource(uint32_t index,
2069 struct cam_vfe_bus_ver2_priv *ver2_bus_priv,
2070 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info,
2071 struct cam_isp_resource_node *vfe_out)
2072{
2073 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL;
2074 int rc = 0;
2075
2076 rsrc_data = kzalloc(sizeof(struct cam_vfe_bus_ver2_vfe_out_data),
2077 GFP_KERNEL);
2078 if (!rsrc_data) {
Harsh Shaha1af8822017-05-11 22:06:36 -07002079 rc = -ENOMEM;
2080 return rc;
2081 }
2082 vfe_out->res_priv = rsrc_data;
2083
2084 vfe_out->res_type = CAM_ISP_RESOURCE_VFE_OUT;
2085 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
2086 INIT_LIST_HEAD(&vfe_out->list);
2087
2088 rsrc_data->out_type = index;
2089 rsrc_data->common_data = &ver2_bus_priv->common_data;
2090 rsrc_data->max_width =
2091 ver2_hw_info->vfe_out_hw_info[index].max_width;
2092 rsrc_data->max_height =
2093 ver2_hw_info->vfe_out_hw_info[index].max_height;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002094 rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shaha1af8822017-05-11 22:06:36 -07002095
2096 vfe_out->start = cam_vfe_bus_start_vfe_out;
2097 vfe_out->stop = cam_vfe_bus_stop_vfe_out;
2098 vfe_out->top_half_handler = cam_vfe_bus_handle_vfe_out_done_top_half;
2099 vfe_out->bottom_half_handler =
2100 cam_vfe_bus_handle_vfe_out_done_bottom_half;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002101 vfe_out->process_cmd = cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002102 vfe_out->hw_intf = ver2_bus_priv->common_data.hw_intf;
2103
2104 return 0;
2105}
2106
Harsh Shah545df9a2017-06-16 16:43:17 -07002107static int cam_vfe_bus_deinit_vfe_out_resource(
2108 struct cam_isp_resource_node *vfe_out)
2109{
2110 struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = vfe_out->res_priv;
2111
2112 vfe_out->start = NULL;
2113 vfe_out->stop = NULL;
2114 vfe_out->top_half_handler = NULL;
2115 vfe_out->bottom_half_handler = NULL;
2116 vfe_out->hw_intf = NULL;
2117
2118 vfe_out->res_state = CAM_ISP_RESOURCE_STATE_UNAVAILABLE;
2119 INIT_LIST_HEAD(&vfe_out->list);
2120 vfe_out->res_priv = NULL;
2121
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002122 if (!rsrc_data)
Harsh Shah545df9a2017-06-16 16:43:17 -07002123 return -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002124 kfree(rsrc_data);
2125
2126 return 0;
2127}
2128
Harsh Shaha1af8822017-05-11 22:06:36 -07002129static int cam_vfe_bus_ver2_handle_irq(uint32_t evt_id,
2130 struct cam_irq_th_payload *th_payload)
2131{
Harsh Shaha1af8822017-05-11 22:06:36 -07002132 struct cam_vfe_bus_ver2_priv *bus_priv;
Harsh Shaha1af8822017-05-11 22:06:36 -07002133
Harsh Shah19f55812017-06-26 18:58:49 -07002134 bus_priv = th_payload->handler_priv;
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002135 CAM_DBG(CAM_ISP, "Enter");
Harsh Shah19f55812017-06-26 18:58:49 -07002136 return cam_irq_controller_handle_irq(evt_id,
2137 bus_priv->common_data.bus_irq_controller);
Harsh Shaha1af8822017-05-11 22:06:36 -07002138}
2139
2140static int cam_vfe_bus_update_buf(void *priv, void *cmd_args,
2141 uint32_t arg_size)
2142{
2143 struct cam_vfe_bus_ver2_priv *bus_priv;
2144 struct cam_isp_hw_get_buf_update *update_buf;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002145 struct cam_buf_io_cfg *io_cfg;
Harsh Shaha1af8822017-05-11 22:06:36 -07002146 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2147 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002148 uint32_t *reg_val_pair;
2149 uint32_t i, j, size = 0;
Junzhe Zou193d78c2017-05-16 15:10:54 -07002150 uint32_t frame_inc = 0;
Harsh Shaha1af8822017-05-11 22:06:36 -07002151
2152 /*
2153 * Need the entire buf io config so we can get the stride info
2154 * for the wm.
2155 */
2156
2157 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2158 update_buf = (struct cam_isp_hw_get_buf_update *) cmd_args;
2159
2160 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2161 update_buf->cdm.res->res_priv;
2162
2163 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002164 CAM_ERR(CAM_ISP, "Failed! Invalid data");
Harsh Shaha1af8822017-05-11 22:06:36 -07002165 return -EINVAL;
2166 }
2167
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002168 if (update_buf->num_buf != vfe_out_data->num_wm) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002169 CAM_ERR(CAM_ISP,
2170 "Failed! Invalid number buffers:%d required:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002171 update_buf->num_buf, vfe_out_data->num_wm);
Junzhe Zou193d78c2017-05-16 15:10:54 -07002172 return -EINVAL;
Harsh Shaha1af8822017-05-11 22:06:36 -07002173 }
2174
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002175 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2176 io_cfg = update_buf->io_cfg;
2177
2178 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
Junzhe Zou193d78c2017-05-16 15:10:54 -07002179 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002180 CAM_ERR(CAM_ISP,
2181 "reg_val_pair %d exceeds the array limit %lu",
Junzhe Zou193d78c2017-05-16 15:10:54 -07002182 j, MAX_REG_VAL_PAIR_SIZE);
2183 return -ENOMEM;
2184 }
2185
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002186 wm_data = vfe_out_data->wm_res[i]->res_priv;
2187
2188 /* For initial configuration program all bus registers */
Ravikishore Pampanaad6bc902017-07-12 19:37:06 +05302189 if ((wm_data->stride != io_cfg->planes[i].plane_stride ||
2190 !wm_data->init_cfg_done) && (wm_data->index >= 3)) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002191 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2192 wm_data->hw_regs->stride,
2193 io_cfg->planes[i].plane_stride);
2194 wm_data->stride = io_cfg->planes[i].plane_stride;
2195 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002196 CAM_DBG(CAM_ISP, "image stride 0x%x", wm_data->stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002197
2198 if (wm_data->framedrop_pattern != io_cfg->framedrop_pattern ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002199 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002200 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2201 wm_data->hw_regs->framedrop_pattern,
2202 io_cfg->framedrop_pattern);
2203 wm_data->framedrop_pattern = io_cfg->framedrop_pattern;
2204 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002205 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2206 wm_data->framedrop_pattern);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002207
2208 if (wm_data->framedrop_period != io_cfg->framedrop_period ||
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002209 !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002210 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2211 wm_data->hw_regs->framedrop_period,
2212 io_cfg->framedrop_period);
2213 wm_data->framedrop_period = io_cfg->framedrop_period;
2214 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002215 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2216 wm_data->framedrop_period);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002217
2218 if (wm_data->irq_subsample_period != io_cfg->subsample_period
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002219 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002220 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2221 wm_data->hw_regs->irq_subsample_period,
2222 io_cfg->subsample_period);
2223 wm_data->irq_subsample_period =
2224 io_cfg->subsample_period;
2225 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002226 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002227 wm_data->irq_subsample_period);
2228
2229 if (wm_data->irq_subsample_pattern != io_cfg->subsample_pattern
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002230 || !wm_data->hfr_cfg_done) {
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002231 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2232 wm_data->hw_regs->irq_subsample_pattern,
2233 io_cfg->subsample_pattern);
2234 wm_data->irq_subsample_pattern =
2235 io_cfg->subsample_pattern;
2236 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002237 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002238 wm_data->irq_subsample_pattern);
2239
2240 if (wm_data->en_ubwc) {
2241 if (!wm_data->hw_regs->ubwc_regs) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002242 CAM_ERR(CAM_ISP,
2243 "No UBWC register to configure.");
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002244 return -EINVAL;
2245 }
2246 if (wm_data->packer_cfg !=
2247 io_cfg->planes[i].packer_config ||
2248 !wm_data->init_cfg_done) {
2249 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2250 wm_data->hw_regs->packer_cfg,
2251 io_cfg->planes[i].packer_config);
2252 wm_data->packer_cfg =
2253 io_cfg->planes[i].packer_config;
2254 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002255 CAM_DBG(CAM_ISP, "packer cfg 0x%x",
2256 wm_data->packer_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002257
2258 if (wm_data->tile_cfg != io_cfg->planes[i].tile_config
2259 || !wm_data->init_cfg_done) {
2260 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2261 wm_data->hw_regs->ubwc_regs->tile_cfg,
2262 io_cfg->planes[i].tile_config);
2263 wm_data->tile_cfg =
2264 io_cfg->planes[i].tile_config;
2265 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002266 CAM_DBG(CAM_ISP, "tile cfg 0x%x", wm_data->tile_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002267
2268 if (wm_data->h_init != io_cfg->planes[i].h_init ||
2269 !wm_data->init_cfg_done) {
2270 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2271 wm_data->hw_regs->ubwc_regs->h_init,
2272 io_cfg->planes[i].h_init);
2273 wm_data->h_init = io_cfg->planes[i].h_init;
2274 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002275 CAM_DBG(CAM_ISP, "h_init 0x%x", wm_data->h_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002276
2277 if (wm_data->v_init != io_cfg->planes[i].v_init ||
2278 !wm_data->init_cfg_done) {
2279 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2280 wm_data->hw_regs->ubwc_regs->v_init,
2281 io_cfg->planes[i].v_init);
2282 wm_data->v_init = io_cfg->planes[i].v_init;
2283 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002284 CAM_DBG(CAM_ISP, "v_init 0x%x", wm_data->v_init);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002285
2286 if (wm_data->ubwc_meta_stride !=
2287 io_cfg->planes[i].meta_stride ||
2288 !wm_data->init_cfg_done) {
2289 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2290 wm_data->hw_regs->ubwc_regs->
2291 meta_stride,
2292 io_cfg->planes[i].meta_stride);
2293 wm_data->ubwc_meta_stride =
2294 io_cfg->planes[i].meta_stride;
2295 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002296 CAM_DBG(CAM_ISP, "meta stride 0x%x",
2297 wm_data->ubwc_meta_stride);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002298
2299 if (wm_data->ubwc_mode_cfg !=
2300 io_cfg->planes[i].mode_config ||
2301 !wm_data->init_cfg_done) {
2302 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2303 wm_data->hw_regs->ubwc_regs->mode_cfg,
2304 io_cfg->planes[i].mode_config);
2305 wm_data->ubwc_mode_cfg =
2306 io_cfg->planes[i].mode_config;
2307 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002308 CAM_DBG(CAM_ISP, "ubwc mode cfg 0x%x",
2309 wm_data->ubwc_mode_cfg);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002310
2311 if (wm_data->ubwc_meta_offset !=
2312 io_cfg->planes[i].meta_offset ||
2313 !wm_data->init_cfg_done) {
2314 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2315 wm_data->hw_regs->ubwc_regs->
2316 meta_offset,
2317 io_cfg->planes[i].meta_offset);
2318 wm_data->ubwc_meta_offset =
2319 io_cfg->planes[i].meta_offset;
2320 }
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002321 CAM_DBG(CAM_ISP, "ubwc meta offset 0x%x",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002322 wm_data->ubwc_meta_offset);
2323
2324 /* UBWC meta address */
2325 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2326 wm_data->hw_regs->ubwc_regs->meta_addr,
2327 update_buf->image_buf[i]);
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002328 CAM_DBG(CAM_ISP, "ubwc meta addr 0x%llx",
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002329 update_buf->image_buf[i]);
2330 }
2331
2332 /* WM Image address */
2333 if (wm_data->en_ubwc)
2334 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2335 wm_data->hw_regs->image_addr,
2336 (update_buf->image_buf[i] +
2337 io_cfg->planes[i].meta_size));
2338 else
2339 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2340 wm_data->hw_regs->image_addr,
2341 update_buf->image_buf[i]);
2342
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002343 CAM_DBG(CAM_ISP, "image address 0x%x", reg_val_pair[j-1]);
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002344
Junzhe Zou193d78c2017-05-16 15:10:54 -07002345 frame_inc = io_cfg->planes[i].plane_stride *
2346 io_cfg->planes[i].slice_height;
2347 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2348 wm_data->hw_regs->frame_inc, frame_inc);
2349
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002350 /* enable the WM */
2351 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2352 wm_data->hw_regs->cfg,
2353 wm_data->en_cfg);
2354
2355 /* set initial configuration done */
2356 if (!wm_data->init_cfg_done)
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002357 wm_data->init_cfg_done = true;
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002358 }
2359
2360 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
Harsh Shaha1af8822017-05-11 22:06:36 -07002361
2362 /* cdm util returns dwords, need to convert to bytes */
2363 if ((size * 4) > update_buf->cdm.size) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002364 CAM_ERR(CAM_ISP,
2365 "Failed! Buf size:%d insufficient, expected size:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002366 update_buf->cdm.size, size);
2367 return -ENOMEM;
2368 }
2369
Harsh Shaha1af8822017-05-11 22:06:36 -07002370 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
Jing Zhoua4e9fbe2017-05-15 14:37:21 -07002371 update_buf->cdm.cmd_buf_addr, j/2, reg_val_pair);
2372
Harsh Shaha1af8822017-05-11 22:06:36 -07002373 /* cdm util returns dwords, need to convert to bytes */
2374 update_buf->cdm.used_bytes = size * 4;
2375
2376 return 0;
2377}
2378
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002379static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
2380 uint32_t arg_size)
2381{
2382 struct cam_vfe_bus_ver2_priv *bus_priv;
2383 struct cam_isp_hw_get_hfr_update *update_hfr;
2384 struct cam_vfe_bus_ver2_vfe_out_data *vfe_out_data = NULL;
2385 struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
2386 struct cam_isp_port_hfr_config *hfr_cfg = NULL;
2387 uint32_t *reg_val_pair;
2388 uint32_t i, j, size = 0;
2389
2390 bus_priv = (struct cam_vfe_bus_ver2_priv *) priv;
2391 update_hfr = (struct cam_isp_hw_get_hfr_update *) cmd_args;
2392
2393 vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
2394 update_hfr->cdm.res->res_priv;
2395
2396 if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
2397 CAM_ERR(CAM_ISP, "Failed! Invalid data");
2398 return -EINVAL;
2399 }
2400
2401 reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
2402 hfr_cfg = update_hfr->io_hfr_cfg;
2403
2404 for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
2405 if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
2406 CAM_ERR(CAM_ISP,
2407 "reg_val_pair %d exceeds the array limit %lu",
2408 j, MAX_REG_VAL_PAIR_SIZE);
2409 return -ENOMEM;
2410 }
2411
2412 wm_data = vfe_out_data->wm_res[i]->res_priv;
2413
2414 if ((wm_data->framedrop_pattern !=
2415 hfr_cfg->framedrop_pattern) ||
2416 !wm_data->hfr_cfg_done) {
2417 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2418 wm_data->hw_regs->framedrop_pattern,
2419 hfr_cfg->framedrop_pattern);
2420 wm_data->framedrop_pattern = hfr_cfg->framedrop_pattern;
2421 }
2422 CAM_DBG(CAM_ISP, "framedrop pattern 0x%x",
2423 wm_data->framedrop_pattern);
2424
2425 if (wm_data->framedrop_period != hfr_cfg->framedrop_period ||
2426 !wm_data->hfr_cfg_done) {
2427 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2428 wm_data->hw_regs->framedrop_period,
2429 hfr_cfg->framedrop_period);
2430 wm_data->framedrop_period = hfr_cfg->framedrop_period;
2431 }
2432 CAM_DBG(CAM_ISP, "framedrop period 0x%x",
2433 wm_data->framedrop_period);
2434
2435 if (wm_data->irq_subsample_period != hfr_cfg->subsample_period
2436 || !wm_data->hfr_cfg_done) {
2437 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2438 wm_data->hw_regs->irq_subsample_period,
2439 hfr_cfg->subsample_period);
2440 wm_data->irq_subsample_period =
2441 hfr_cfg->subsample_period;
2442 }
2443 CAM_DBG(CAM_ISP, "irq subsample period 0x%x",
2444 wm_data->irq_subsample_period);
2445
2446 if (wm_data->irq_subsample_pattern != hfr_cfg->subsample_pattern
2447 || !wm_data->hfr_cfg_done) {
2448 CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
2449 wm_data->hw_regs->irq_subsample_pattern,
2450 hfr_cfg->subsample_pattern);
2451 wm_data->irq_subsample_pattern =
2452 hfr_cfg->subsample_pattern;
2453 }
2454 CAM_DBG(CAM_ISP, "irq subsample pattern 0x%x",
2455 wm_data->irq_subsample_pattern);
2456
2457 /* set initial configuration done */
2458 if (!wm_data->hfr_cfg_done)
2459 wm_data->hfr_cfg_done = true;
2460 }
2461
2462 size = vfe_out_data->cdm_util_ops->cdm_required_size_reg_random(j/2);
2463
2464 /* cdm util returns dwords, need to convert to bytes */
2465 if ((size * 4) > update_hfr->cdm.size) {
2466 CAM_ERR(CAM_ISP,
2467 "Failed! Buf size:%d insufficient, expected size:%d",
2468 update_hfr->cdm.size, size);
2469 return -ENOMEM;
2470 }
2471
2472 vfe_out_data->cdm_util_ops->cdm_write_regrandom(
2473 update_hfr->cdm.cmd_buf_addr, j/2, reg_val_pair);
2474
2475 /* cdm util returns dwords, need to convert to bytes */
2476 update_hfr->cdm.used_bytes = size * 4;
2477
2478 return 0;
2479}
2480
Harsh Shah19f55812017-06-26 18:58:49 -07002481static int cam_vfe_bus_start_hw(void *hw_priv,
2482 void *start_hw_args, uint32_t arg_size)
2483{
2484 return cam_vfe_bus_start_vfe_out(hw_priv);
2485}
2486
2487static int cam_vfe_bus_stop_hw(void *hw_priv,
2488 void *stop_hw_args, uint32_t arg_size)
2489{
2490 return cam_vfe_bus_stop_vfe_out(hw_priv);
2491}
2492
2493static int cam_vfe_bus_init_hw(void *hw_priv,
2494 void *init_hw_args, uint32_t arg_size)
2495{
2496 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2497 uint32_t top_irq_reg_mask[2] = {0};
2498
2499 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002500 CAM_ERR(CAM_ISP, "Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002501 return -EINVAL;
2502 }
2503
2504 top_irq_reg_mask[0] = (1 << 9);
2505
2506 bus_priv->irq_handle = cam_irq_controller_subscribe_irq(
2507 bus_priv->common_data.vfe_irq_controller,
2508 CAM_IRQ_PRIORITY_2,
2509 top_irq_reg_mask,
2510 bus_priv,
2511 cam_vfe_bus_ver2_handle_irq,
2512 NULL,
2513 NULL,
2514 NULL);
2515
2516 if (bus_priv->irq_handle <= 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002517 CAM_ERR(CAM_ISP, "Failed to subscribe BUS IRQ");
Harsh Shah19f55812017-06-26 18:58:49 -07002518 return -EFAULT;
2519 }
2520
2521 return 0;
2522}
2523
2524static int cam_vfe_bus_deinit_hw(void *hw_priv,
2525 void *deinit_hw_args, uint32_t arg_size)
2526{
2527 struct cam_vfe_bus_ver2_priv *bus_priv = hw_priv;
2528 int rc;
2529
2530 if (!bus_priv || (bus_priv->irq_handle <= 0)) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002531 CAM_ERR(CAM_ISP, "Error: Invalid args");
Harsh Shah19f55812017-06-26 18:58:49 -07002532 return -EINVAL;
2533 }
2534
2535 rc = cam_irq_controller_unsubscribe_irq(
2536 bus_priv->common_data.vfe_irq_controller,
2537 bus_priv->irq_handle);
2538 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002539 CAM_ERR(CAM_ISP, "Failed to unsubscribe irq rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002540
2541 return rc;
2542}
2543
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002544static int __cam_vfe_bus_process_cmd(void *priv,
2545 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2546{
2547 return cam_vfe_bus_process_cmd(priv, cmd_type, cmd_args, arg_size);
2548}
2549
2550static int cam_vfe_bus_process_cmd(
2551 struct cam_isp_resource_node *priv,
Harsh Shaha1af8822017-05-11 22:06:36 -07002552 uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
2553{
2554 int rc = -EINVAL;
2555
2556 if (!priv || !cmd_args) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002557 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments");
Harsh Shaha1af8822017-05-11 22:06:36 -07002558 return -EINVAL;
2559 }
2560
2561 switch (cmd_type) {
2562 case CAM_VFE_HW_CMD_GET_BUF_UPDATE:
2563 rc = cam_vfe_bus_update_buf(priv, cmd_args, arg_size);
2564 break;
Pavan Kumar Chilamkurthi649cdf92017-08-15 01:40:57 -07002565 case CAM_VFE_HW_CMD_GET_HFR_UPDATE:
2566 rc = cam_vfe_bus_update_hfr(priv, cmd_args, arg_size);
2567 break;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002568 case CAM_VFE_HW_CMD_GET_SECURE_MODE:
2569 rc = cam_vfe_bus_get_secure_mode(priv, cmd_args, arg_size);
2570 break;
Harsh Shaha1af8822017-05-11 22:06:36 -07002571 default:
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002572 CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
Harsh Shaha1af8822017-05-11 22:06:36 -07002573 cmd_type);
2574 break;
2575 }
2576
2577 return rc;
2578}
2579
2580int cam_vfe_bus_ver2_init(
Harsh Shah19f55812017-06-26 18:58:49 -07002581 struct cam_hw_soc_info *soc_info,
Harsh Shaha1af8822017-05-11 22:06:36 -07002582 struct cam_hw_intf *hw_intf,
2583 void *bus_hw_info,
2584 void *vfe_irq_controller,
2585 struct cam_vfe_bus **vfe_bus)
2586{
2587 int i, rc = 0;
2588 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2589 struct cam_vfe_bus *vfe_bus_local;
2590 struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info;
2591
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002592 CAM_DBG(CAM_ISP, "Enter");
Harsh Shaha1af8822017-05-11 22:06:36 -07002593
Harsh Shah19f55812017-06-26 18:58:49 -07002594 if (!soc_info || !hw_intf || !bus_hw_info || !vfe_irq_controller) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002595 CAM_ERR(CAM_ISP,
2596 "Inval_prms soc_info:%pK hw_intf:%pK hw_info%pK",
2597 soc_info, hw_intf, bus_hw_info);
2598 CAM_ERR(CAM_ISP, "controller: %pK", vfe_irq_controller);
Harsh Shah19f55812017-06-26 18:58:49 -07002599 rc = -EINVAL;
2600 goto end;
2601 }
2602
Harsh Shaha1af8822017-05-11 22:06:36 -07002603 vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL);
2604 if (!vfe_bus_local) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002605 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus");
Harsh Shaha1af8822017-05-11 22:06:36 -07002606 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002607 goto end;
Harsh Shaha1af8822017-05-11 22:06:36 -07002608 }
2609
2610 bus_priv = kzalloc(sizeof(struct cam_vfe_bus_ver2_priv),
2611 GFP_KERNEL);
2612 if (!bus_priv) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002613 CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus_priv");
Harsh Shaha1af8822017-05-11 22:06:36 -07002614 rc = -ENOMEM;
Harsh Shah545df9a2017-06-16 16:43:17 -07002615 goto free_bus_local;
Harsh Shaha1af8822017-05-11 22:06:36 -07002616 }
2617 vfe_bus_local->bus_priv = bus_priv;
2618
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002619 bus_priv->common_data.num_sec_out = 0;
2620 bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE;
Harsh Shah19f55812017-06-26 18:58:49 -07002621 bus_priv->common_data.core_index = soc_info->index;
2622 bus_priv->common_data.mem_base =
2623 CAM_SOC_GET_REG_MAP_START(soc_info, VFE_CORE_BASE_IDX);
Harsh Shaha1af8822017-05-11 22:06:36 -07002624 bus_priv->common_data.hw_intf = hw_intf;
2625 bus_priv->common_data.vfe_irq_controller = vfe_irq_controller;
2626 bus_priv->common_data.common_reg = &ver2_hw_info->common_reg;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002627 mutex_init(&bus_priv->common_data.bus_mutex);
Harsh Shaha1af8822017-05-11 22:06:36 -07002628
Harsh Shah19f55812017-06-26 18:58:49 -07002629 rc = cam_irq_controller_init(drv_name, bus_priv->common_data.mem_base,
2630 &ver2_hw_info->common_reg.irq_reg_info,
2631 &bus_priv->common_data.bus_irq_controller);
2632 if (rc) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002633 CAM_ERR(CAM_ISP, "cam_irq_controller_init failed");
Harsh Shah19f55812017-06-26 18:58:49 -07002634 goto free_bus_priv;
2635 }
2636
Harsh Shaha1af8822017-05-11 22:06:36 -07002637 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2638 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2639 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2640
2641 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2642 rc = cam_vfe_bus_init_wm_resource(i, bus_priv, bus_hw_info,
2643 &bus_priv->bus_client[i]);
2644 if (rc < 0) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002645 CAM_ERR(CAM_ISP, "Init WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002646 goto deinit_wm;
Harsh Shaha1af8822017-05-11 22:06:36 -07002647 }
2648 }
2649
2650 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2651 rc = cam_vfe_bus_init_comp_grp(i, bus_priv, bus_hw_info,
2652 &bus_priv->comp_grp[i]);
2653 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002654 CAM_ERR(CAM_ISP, "Init Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002655 goto deinit_comp_grp;
Harsh Shaha1af8822017-05-11 22:06:36 -07002656 }
2657 }
2658
2659 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2660 rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info,
2661 &bus_priv->vfe_out[i]);
2662 if (rc < 0) {
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002663 CAM_ERR(CAM_ISP, "Init VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002664 goto deinit_vfe_out;
Harsh Shaha1af8822017-05-11 22:06:36 -07002665 }
2666 }
2667
Harsh Shah19f55812017-06-26 18:58:49 -07002668 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2669 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++) {
2670 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
2671 list_add_tail(&bus_priv->common_data.evt_payload[i].list,
2672 &bus_priv->common_data.free_payload_list);
Harsh Shaha1af8822017-05-11 22:06:36 -07002673 }
2674
Harsh Shah19f55812017-06-26 18:58:49 -07002675 vfe_bus_local->hw_ops.reserve = cam_vfe_bus_acquire_vfe_out;
2676 vfe_bus_local->hw_ops.release = cam_vfe_bus_release_vfe_out;
2677 vfe_bus_local->hw_ops.start = cam_vfe_bus_start_hw;
2678 vfe_bus_local->hw_ops.stop = cam_vfe_bus_stop_hw;
2679 vfe_bus_local->hw_ops.init = cam_vfe_bus_init_hw;
2680 vfe_bus_local->hw_ops.deinit = cam_vfe_bus_deinit_hw;
2681 vfe_bus_local->top_half_handler = cam_vfe_bus_ver2_handle_irq;
Harsh Shaha1af8822017-05-11 22:06:36 -07002682 vfe_bus_local->bottom_half_handler = NULL;
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002683 vfe_bus_local->hw_ops.process_cmd = __cam_vfe_bus_process_cmd;
Harsh Shaha1af8822017-05-11 22:06:36 -07002684
2685 *vfe_bus = vfe_bus_local;
2686
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002687 CAM_DBG(CAM_ISP, "Exit");
Harsh Shaha1af8822017-05-11 22:06:36 -07002688 return rc;
2689
Harsh Shah545df9a2017-06-16 16:43:17 -07002690deinit_vfe_out:
2691 if (i < 0)
2692 i = CAM_VFE_BUS_VER2_VFE_OUT_MAX;
2693 for (--i; i >= 0; i--)
2694 cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2695
2696deinit_comp_grp:
2697 if (i < 0)
2698 i = CAM_VFE_BUS_VER2_COMP_GRP_MAX;
2699 for (--i; i >= 0; i--)
2700 cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2701
2702deinit_wm:
2703 if (i < 0)
2704 i = CAM_VFE_BUS_VER2_MAX_CLIENTS;
2705 for (--i; i >= 0; i--)
2706 cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2707
Harsh Shah19f55812017-06-26 18:58:49 -07002708free_bus_priv:
Harsh Shaha1af8822017-05-11 22:06:36 -07002709 kfree(vfe_bus_local->bus_priv);
Harsh Shah545df9a2017-06-16 16:43:17 -07002710
2711free_bus_local:
Harsh Shaha1af8822017-05-11 22:06:36 -07002712 kfree(vfe_bus_local);
Harsh Shah545df9a2017-06-16 16:43:17 -07002713
2714end:
Harsh Shaha1af8822017-05-11 22:06:36 -07002715 return rc;
2716}
Harsh Shah545df9a2017-06-16 16:43:17 -07002717
2718int cam_vfe_bus_ver2_deinit(
2719 struct cam_vfe_bus **vfe_bus)
2720{
2721 int i, rc = 0;
2722 struct cam_vfe_bus_ver2_priv *bus_priv = NULL;
2723 struct cam_vfe_bus *vfe_bus_local;
2724
2725 if (!vfe_bus || !*vfe_bus) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002726 CAM_ERR(CAM_ISP, "Invalid input");
Harsh Shah545df9a2017-06-16 16:43:17 -07002727 return -EINVAL;
2728 }
2729 vfe_bus_local = *vfe_bus;
2730
2731 bus_priv = vfe_bus_local->bus_priv;
2732 if (!bus_priv) {
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002733 CAM_ERR(CAM_ISP, "bus_priv is NULL");
Harsh Shah545df9a2017-06-16 16:43:17 -07002734 rc = -ENODEV;
2735 goto free_bus_local;
2736 }
2737
Harsh Shah19f55812017-06-26 18:58:49 -07002738 INIT_LIST_HEAD(&bus_priv->common_data.free_payload_list);
2739 for (i = 0; i < CAM_VFE_BUS_VER2_PAYLOAD_MAX; i++)
2740 INIT_LIST_HEAD(&bus_priv->common_data.evt_payload[i].list);
Harsh Shah545df9a2017-06-16 16:43:17 -07002741
2742 for (i = 0; i < CAM_VFE_BUS_VER2_MAX_CLIENTS; i++) {
2743 rc = cam_vfe_bus_deinit_wm_resource(&bus_priv->bus_client[i]);
2744 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002745 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002746 "Deinit WM failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002747 }
2748
2749 for (i = 0; i < CAM_VFE_BUS_VER2_COMP_GRP_MAX; i++) {
2750 rc = cam_vfe_bus_deinit_comp_grp(&bus_priv->comp_grp[i]);
2751 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002752 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002753 "Deinit Comp Grp failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002754 }
2755
2756 for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) {
2757 rc = cam_vfe_bus_deinit_vfe_out_resource(&bus_priv->vfe_out[i]);
2758 if (rc < 0)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002759 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002760 "Deinit VFE Out failed rc=%d", rc);
Harsh Shah545df9a2017-06-16 16:43:17 -07002761 }
2762
2763 INIT_LIST_HEAD(&bus_priv->free_comp_grp);
2764 INIT_LIST_HEAD(&bus_priv->free_dual_comp_grp);
2765 INIT_LIST_HEAD(&bus_priv->used_comp_grp);
2766
Harsh Shah19f55812017-06-26 18:58:49 -07002767 rc = cam_irq_controller_deinit(
2768 &bus_priv->common_data.bus_irq_controller);
2769 if (rc)
Jigarkumar Zala7c4fd372017-07-24 18:43:04 -07002770 CAM_ERR(CAM_ISP,
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002771 "Deinit IRQ Controller failed rc=%d", rc);
Harsh Shah19f55812017-06-26 18:58:49 -07002772
Lakshmi Narayana Kalavala2c714282017-09-08 12:27:36 -07002773 mutex_destroy(&bus_priv->common_data.bus_mutex);
Harsh Shah545df9a2017-06-16 16:43:17 -07002774 kfree(vfe_bus_local->bus_priv);
2775
2776free_bus_local:
2777 kfree(vfe_bus_local);
2778
2779 *vfe_bus = NULL;
2780
2781 return rc;
2782}
2783