1 /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
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.
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.
13 #include <linux/module.h>
14 #include <linux/ratelimit.h>
15 #include <asm/div64.h>
16 #include "msm_isp40.h"
17 #include "msm_isp_util.h"
18 #include "msm_isp_axi_util.h"
19 #include "msm_isp_stats_util.h"
22 #include "msm_camera_io_util.h"
23 #include "msm_isp47.h"
24 #include "linux/iopoll.h"
27 #define CDBG(fmt, args...) pr_debug(fmt, ##args)
29 #define VFE40_BURST_LEN 1
30 #define VFE40_BURST_LEN_8916_VERSION 2
31 #define VFE40_BURST_LEN_8952_VERSION 3
32 #define VFE40_WM_BIT_SHIFT 4
33 #define VFE40_WM_BIT_SHIFT_8976_VERSION 3
34 #define VFE40_STATS_BURST_LEN 1
35 #define VFE40_STATS_BURST_LEN_8916_VERSION 2
36 #define VFE40_FETCH_BURST_LEN 3
37 #define VFE40_UB_SIZE 1536 /* 1536 * 128 bits = 24KB */
38 #define VFE40_STATS_SIZE 392
39 #define VFE40_UB_SIZE_8952 2048 /* 2048 * 128 bits = 32KB */
40 #define VFE40_UB_SIZE_8916 3072 /* 3072 * 128 bits = 48KB */
41 #define VFE40_EQUAL_SLICE_UB 190 /* (UB_SIZE - STATS SIZE)/6 */
42 #define VFE40_EQUAL_SLICE_UB_8916 236
43 #define VFE40_TOTAL_WM_UB 1144 /* UB_SIZE - STATS SIZE */
44 #define VFE40_TOTAL_WM_UB_8916 2680
45 #define VFE40_WM_BASE(idx) (0x6C + 0x24 * idx)
46 #define VFE40_RDI_BASE(idx) (0x2E8 + 0x4 * idx)
47 #define VFE40_XBAR_BASE(idx) (0x58 + 0x4 * (idx / 2))
48 #define VFE40_XBAR_SHIFT(idx) ((idx%2) ? 16 : 0)
49 #define VFE40_PING_PONG_BASE(wm, ping_pong) \
50 (VFE40_WM_BASE(wm) + 0x4 * (1 + ((~ping_pong) & 0x1)))
52 #define VFE40_BUS_RD_CGC_OVERRIDE_BIT 16
54 #define STATS_IDX_BE 0
55 #define STATS_IDX_BG 1
56 #define STATS_IDX_BF 2
57 #define STATS_IDX_AWB 3
58 #define STATS_IDX_RS 4
59 #define STATS_IDX_CS 5
60 #define STATS_IDX_IHIST 6
61 #define STATS_IDX_BHIST 7
63 static uint8_t stats_pingpong_offset_map[] = {
64 8, 9, 10, 11, 12, 13, 14, 15};
66 #define VFE40_NUM_STATS_TYPE 8
67 #define VFE40_STATS_BASE(idx) (0x168 + 0x18 * idx)
68 #define VFE40_STATS_PING_PONG_BASE(idx, ping_pong) \
69 (VFE40_STATS_BASE(idx) + 0x4 * \
70 (~(ping_pong >> (stats_pingpong_offset_map[idx])) & 0x1))
72 #define VFE40_VBIF_CLKON 0x4
73 #define VFE40_VBIF_IN_RD_LIM_CONF0 0xB0
74 #define VFE40_VBIF_IN_RD_LIM_CONF1 0xB4
75 #define VFE40_VBIF_IN_RD_LIM_CONF2 0xB8
76 #define VFE40_VBIF_IN_WR_LIM_CONF0 0xC0
77 #define VFE40_VBIF_IN_WR_LIM_CONF1 0xC4
78 #define VFE40_VBIF_IN_WR_LIM_CONF2 0xC8
79 #define VFE40_VBIF_OUT_RD_LIM_CONF0 0xD0
80 #define VFE40_VBIF_OUT_WR_LIM_CONF0 0xD4
81 #define VFE40_VBIF_DDR_OUT_MAX_BURST 0xD8
82 #define VFE40_VBIF_OCMEM_OUT_MAX_BURST 0xDC
83 #define VFE40_VBIF_ARB_CTL 0xF0
84 #define VFE40_VBIF_ROUND_ROBIN_QOS_ARB 0x124
85 #define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF0 0x160
86 #define VFE40_VBIF_OUT_AXI_AMEMTYPE_CONF1 0x164
87 #define VFE40_VBIF_OUT_AXI_AOOO_EN 0x178
88 #define VFE40_VBIF_OUT_AXI_AOOO 0x17C
90 #define VFE40_BUS_BDG_QOS_CFG_0 0x000002C4
91 #define VFE40_BUS_BDG_QOS_CFG_1 0x000002C8
92 #define VFE40_BUS_BDG_QOS_CFG_2 0x000002CC
93 #define VFE40_BUS_BDG_QOS_CFG_3 0x000002D0
94 #define VFE40_BUS_BDG_QOS_CFG_4 0x000002D4
95 #define VFE40_BUS_BDG_QOS_CFG_5 0x000002D8
96 #define VFE40_BUS_BDG_QOS_CFG_6 0x000002DC
97 #define VFE40_BUS_BDG_QOS_CFG_7 0x000002E0
99 #define VFE40_CLK_IDX 2
101 static uint32_t msm_vfe40_ub_reg_offset(struct vfe_device *vfe_dev, int idx)
103 return (VFE40_WM_BASE(idx) + 0x10);
106 static uint32_t msm_vfe40_get_ub_size(struct vfe_device *vfe_dev)
108 if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
109 vfe_dev->vfe_hw_version == VFE40_8939_VERSION ||
110 vfe_dev->vfe_hw_version == VFE40_8937_VERSION ||
111 vfe_dev->vfe_hw_version == VFE40_8953_VERSION ||
112 vfe_dev->vfe_hw_version == VFE40_8917_VERSION) {
113 vfe_dev->ub_info->wm_ub = VFE40_TOTAL_WM_UB_8916;
114 return VFE40_TOTAL_WM_UB_8916;
116 return VFE40_TOTAL_WM_UB;
119 static void msm_vfe40_config_irq(struct vfe_device *vfe_dev,
120 uint32_t irq0_mask, uint32_t irq1_mask,
121 enum msm_isp_irq_operation oper)
124 case MSM_ISP_IRQ_ENABLE:
125 vfe_dev->irq0_mask |= irq0_mask;
126 vfe_dev->irq1_mask |= irq1_mask;
127 msm_camera_io_w(irq0_mask, vfe_dev->vfe_base + 0x30);
128 msm_camera_io_w(irq0_mask, vfe_dev->vfe_base + 0x34);
129 msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
131 case MSM_ISP_IRQ_DISABLE:
132 vfe_dev->irq0_mask &= ~irq0_mask;
133 vfe_dev->irq1_mask &= ~irq1_mask;
135 case MSM_ISP_IRQ_SET:
136 vfe_dev->irq0_mask = irq0_mask;
137 vfe_dev->irq1_mask = irq1_mask;
138 msm_camera_io_w(irq0_mask, vfe_dev->vfe_base + 0x30);
139 msm_camera_io_w(irq0_mask, vfe_dev->vfe_base + 0x34);
140 msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
142 msm_camera_io_w_mb(vfe_dev->irq0_mask, vfe_dev->vfe_base + 0x28);
143 msm_camera_io_w_mb(vfe_dev->irq1_mask, vfe_dev->vfe_base + 0x2C);
146 static int32_t msm_vfe40_init_qos_parms(struct vfe_device *vfe_dev,
147 struct msm_vfe_hw_init_parms *qos_parms,
148 struct msm_vfe_hw_init_parms *ds_parms)
150 void __iomem *vfebase = vfe_dev->vfe_base;
151 struct device_node *of_node;
152 uint32_t *ds_settings = NULL, *ds_regs = NULL, ds_entries = 0;
153 int32_t i = 0 , rc = 0;
154 uint32_t *qos_settings = NULL, *qos_regs = NULL, qos_entries = 0;
155 of_node = vfe_dev->pdev->dev.of_node;
157 rc = of_property_read_u32(of_node, qos_parms->entries,
159 if (rc < 0 || !qos_entries) {
160 pr_err("%s: NO QOS entries found\n", __func__);
162 qos_settings = kzalloc(sizeof(uint32_t) * qos_entries,
165 pr_err("%s:%d No memory\n", __func__, __LINE__);
168 qos_regs = kzalloc(sizeof(uint32_t) * qos_entries,
171 pr_err("%s:%d No memory\n", __func__, __LINE__);
175 rc = of_property_read_u32_array(of_node, qos_parms->regs,
176 qos_regs, qos_entries);
178 pr_err("%s: NO QOS BUS BDG info\n", __func__);
180 if (qos_parms->settings) {
181 rc = of_property_read_u32_array(of_node,
183 qos_settings, qos_entries);
185 pr_err("%s: NO QOS settings\n",
188 for (i = 0; i < qos_entries; i++)
189 msm_camera_io_w(qos_settings[i],
190 vfebase + qos_regs[i]);
197 rc = of_property_read_u32(of_node, ds_parms->entries,
199 if (rc < 0 || !ds_entries) {
200 pr_err("%s: NO D/S entries found\n", __func__);
202 ds_settings = kcalloc(ds_entries, sizeof(uint32_t),
205 pr_err("%s:%d No memory\n", __func__, __LINE__);
208 ds_regs = kzalloc(sizeof(uint32_t) * ds_entries,
211 pr_err("%s:%d No memory\n", __func__, __LINE__);
215 rc = of_property_read_u32_array(of_node, ds_parms->regs,
216 ds_regs, ds_entries);
218 pr_err("%s: NO D/S register info\n", __func__);
220 if (ds_parms->settings) {
221 rc = of_property_read_u32_array(of_node,
222 ds_parms->settings, ds_settings,
225 pr_err("%s: NO D/S settings\n",
228 for (i = 0; i < ds_entries; i++)
229 msm_camera_io_w(ds_settings[i],
230 vfebase + ds_regs[i]);
240 static int32_t msm_vfe40_init_vbif_parms(struct vfe_device *vfe_dev,
241 struct msm_vfe_hw_init_parms *vbif_parms)
243 void __iomem *vfe_vbif_base = vfe_dev->vfe_vbif_base;
244 struct device_node *of_node;
245 int32_t i = 0 , rc = 0;
246 uint32_t *vbif_settings = NULL, *vbif_regs = NULL, vbif_entries = 0;
247 of_node = vfe_dev->pdev->dev.of_node;
249 rc = of_property_read_u32(of_node, vbif_parms->entries,
251 if (rc < 0 || !vbif_entries) {
252 pr_err("%s: NO VBIF entries found\n", __func__);
254 vbif_settings = kzalloc(sizeof(uint32_t) * vbif_entries,
256 if (!vbif_settings) {
257 pr_err("%s:%d No memory\n", __func__, __LINE__);
260 vbif_regs = kzalloc(sizeof(uint32_t) * vbif_entries,
263 pr_err("%s:%d No memory\n", __func__, __LINE__);
264 kfree(vbif_settings);
267 rc = of_property_read_u32_array(of_node, vbif_parms->regs,
268 vbif_regs, vbif_entries);
270 pr_err("%s: NO VBIF info\n", __func__);
271 kfree(vbif_settings);
274 rc = of_property_read_u32_array(of_node,
275 vbif_parms->settings,
276 vbif_settings, vbif_entries);
278 pr_err("%s: NO VBIF settings\n",
280 kfree(vbif_settings);
283 for (i = 0; i < vbif_entries; i++)
286 vfe_vbif_base + vbif_regs[i]);
287 kfree(vbif_settings);
295 static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
297 struct msm_vfe_hw_init_parms qos_parms;
298 struct msm_vfe_hw_init_parms vbif_parms;
299 struct msm_vfe_hw_init_parms ds_parms;
301 qos_parms.entries = "qos-entries";
302 qos_parms.regs = "qos-regs";
303 qos_parms.settings = "qos-settings";
304 vbif_parms.entries = "vbif-entries";
305 vbif_parms.regs = "vbif-regs";
306 vbif_parms.settings = "vbif-settings";
307 ds_parms.entries = "ds-entries";
308 ds_parms.regs = "ds-regs";
309 ds_parms.settings = "ds-settings";
311 switch (vfe_dev->vfe_hw_version) {
312 case VFE40_8974V1_VERSION:
313 case VFE40_8x26_VERSION:
314 case VFE40_8916_VERSION:
315 case VFE40_8939_VERSION:
317 case VFE40_8x26V2_VERSION:
318 qos_parms.settings = "qos-v2-settings";
320 case VFE40_8974V2_VERSION:
321 case VFE40_8974V3_VERSION:
322 if (vfe_dev->vfe_hw_version == VFE40_8974V2_VERSION)
323 qos_parms.settings = "qos-v2-settings";
325 qos_parms.settings = "qos-v3-settings";
326 vbif_parms.entries = "vbif-v2-entries";
327 vbif_parms.regs = "vbif-v2-regs";
328 vbif_parms.settings = "vbif-v2-settings";
330 case VFE40_8937_VERSION:
331 case VFE40_8953_VERSION:
332 case VFE40_8917_VERSION:
334 ISP_DBG("%s: No special QOS\n", __func__);
337 msm_vfe40_init_qos_parms(vfe_dev, &qos_parms, &ds_parms);
338 msm_vfe40_init_vbif_parms(vfe_dev, &vbif_parms);
340 msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50);
341 msm_vfe40_config_irq(vfe_dev, 0x800000E0, 0xFEFFFF7E,
345 static void msm_vfe40_clear_status_reg(struct vfe_device *vfe_dev)
347 vfe_dev->irq0_mask = (1 << 31);
348 vfe_dev->irq1_mask = 0;
349 msm_vfe40_config_irq(vfe_dev, (1 << 31), 0,
351 msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
352 msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
353 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
356 static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
357 uint32_t irq_status0, uint32_t irq_status1)
361 if (irq_status0 & (1 << 31)) {
362 spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
363 complete(&vfe_dev->reset_complete);
364 spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
368 static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
369 uint32_t irq_status0, uint32_t irq_status1)
373 if (irq_status1 & (1 << 8)) {
374 spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
375 complete(&vfe_dev->halt_complete);
376 spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
377 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
381 static void msm_vfe40_process_input_irq(struct vfe_device *vfe_dev,
382 uint32_t irq_status0, uint32_t irq_status1,
383 struct msm_isp_timestamp *ts)
385 if (!(irq_status0 & 0x1000003))
388 if (irq_status0 & (1 << 0)) {
389 ISP_DBG("%s: SOF IRQ\n", __func__);
390 msm_isp_increment_frame_id(vfe_dev, VFE_PIX_0, ts);
393 if (irq_status0 & (1 << 24)) {
394 ISP_DBG("%s: Fetch Engine Read IRQ\n", __func__);
395 msm_isp_fetch_engine_done_notify(vfe_dev,
396 &vfe_dev->fetch_engine_info);
399 if (irq_status0 & (1 << 1))
400 ISP_DBG("%s: EOF IRQ\n", __func__);
403 static void msm_vfe40_process_violation_status(
404 struct vfe_device *vfe_dev)
406 uint32_t violation_status = vfe_dev->error_info.violation_status;
407 if (!violation_status)
410 if (violation_status & (1 << 0))
411 pr_err("%s: vfe %d camif violation\n", __func__,
413 if (violation_status & (1 << 1))
414 pr_err("%s: vfe %d black violation\n", __func__,
416 if (violation_status & (1 << 2))
417 pr_err("%s: vfe %d rolloff violation\n", __func__,
419 if (violation_status & (1 << 3))
420 pr_err("%s: demux violation\n", __func__);
421 if (violation_status & (1 << 4))
422 pr_err("%s: demosaic violation\n", __func__);
423 if (violation_status & (1 << 5))
424 pr_err("%s: wb violation\n", __func__);
425 if (violation_status & (1 << 6))
426 pr_err("%s: clf violation\n", __func__);
427 if (violation_status & (1 << 7))
428 pr_err("%s: color correct violation\n", __func__);
429 if (violation_status & (1 << 8))
430 pr_err("%s: rgb lut violation\n", __func__);
431 if (violation_status & (1 << 9))
432 pr_err("%s: la violation\n", __func__);
433 if (violation_status & (1 << 10))
434 pr_err("%s: chroma enhance violation\n", __func__);
435 if (violation_status & (1 << 11))
436 pr_err("%s: chroma supress mce violation\n", __func__);
437 if (violation_status & (1 << 12))
438 pr_err("%s: skin enhance violation\n", __func__);
439 if (violation_status & (1 << 13))
440 pr_err("%s: color tranform enc violation\n", __func__);
441 if (violation_status & (1 << 14))
442 pr_err("%s: color tranform view violation\n", __func__);
443 if (violation_status & (1 << 15))
444 pr_err("%s: scale enc y violation\n", __func__);
445 if (violation_status & (1 << 16))
446 pr_err("%s: scale enc cbcr violation\n", __func__);
447 if (violation_status & (1 << 17))
448 pr_err("%s: scale view y violation\n", __func__);
449 if (violation_status & (1 << 18))
450 pr_err("%s: scale view cbcr violation\n", __func__);
451 if (violation_status & (1 << 19))
452 pr_err("%s: asf enc violation\n", __func__);
453 if (violation_status & (1 << 20))
454 pr_err("%s: asf view violation\n", __func__);
455 if (violation_status & (1 << 21))
456 pr_err("%s: crop enc y violation\n", __func__);
457 if (violation_status & (1 << 22))
458 pr_err("%s: crop enc cbcr violation\n", __func__);
459 if (violation_status & (1 << 23))
460 pr_err("%s: crop view y violation\n", __func__);
461 if (violation_status & (1 << 24))
462 pr_err("%s: crop view cbcr violation\n", __func__);
463 if (violation_status & (1 << 25))
464 pr_err("%s: realign buf y violation\n", __func__);
465 if (violation_status & (1 << 26))
466 pr_err("%s: realign buf cb violation\n", __func__);
467 if (violation_status & (1 << 27))
468 pr_err("%s: realign buf cr violation\n", __func__);
471 static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev)
473 uint32_t error_status1 = vfe_dev->error_info.error_mask1;
474 if (error_status1 & (1 << 0)) {
475 pr_err_ratelimited("%s: vfe %d camif error status: 0x%x\n",
476 __func__, vfe_dev->pdev->id,
477 vfe_dev->error_info.camif_status);
478 msm_camera_io_dump(vfe_dev->vfe_base + 0x2F4, 0x30, 1);
480 if (error_status1 & (1 << 1))
481 pr_err_ratelimited("%s: stats bhist overwrite\n", __func__);
482 if (error_status1 & (1 << 2))
483 pr_err_ratelimited("%s: stats cs overwrite\n", __func__);
484 if (error_status1 & (1 << 3))
485 pr_err_ratelimited("%s: stats ihist overwrite\n", __func__);
486 if (error_status1 & (1 << 4))
487 pr_err_ratelimited("%s: realign buf y overflow\n", __func__);
488 if (error_status1 & (1 << 5))
489 pr_err_ratelimited("%s: realign buf cb overflow\n", __func__);
490 if (error_status1 & (1 << 6))
491 pr_err_ratelimited("%s: realign buf cr overflow\n", __func__);
492 if (error_status1 & (1 << 7)) {
493 msm_vfe40_process_violation_status(vfe_dev);
495 if (error_status1 & (1 << 9)) {
496 vfe_dev->stats->imagemaster0_overflow++;
497 pr_err_ratelimited("%s: image master 0 bus overflow\n",
500 if (error_status1 & (1 << 10)) {
501 vfe_dev->stats->imagemaster1_overflow++;
502 pr_err_ratelimited("%s: image master 1 bus overflow\n",
505 if (error_status1 & (1 << 11)) {
506 vfe_dev->stats->imagemaster2_overflow++;
507 pr_err_ratelimited("%s: image master 2 bus overflow\n",
510 if (error_status1 & (1 << 12)) {
511 vfe_dev->stats->imagemaster3_overflow++;
512 pr_err_ratelimited("%s: image master 3 bus overflow\n",
515 if (error_status1 & (1 << 13)) {
516 vfe_dev->stats->imagemaster4_overflow++;
517 pr_err_ratelimited("%s: image master 4 bus overflow\n",
520 if (error_status1 & (1 << 14)) {
521 vfe_dev->stats->imagemaster5_overflow++;
522 pr_err_ratelimited("%s: image master 5 bus overflow\n",
525 if (error_status1 & (1 << 15)) {
526 vfe_dev->stats->imagemaster6_overflow++;
527 pr_err_ratelimited("%s: image master 6 bus overflow\n",
530 if (error_status1 & (1 << 16)) {
531 vfe_dev->stats->be_overflow++;
532 pr_err_ratelimited("%s: status be bus overflow\n", __func__);
534 if (error_status1 & (1 << 17)) {
535 vfe_dev->stats->bg_overflow++;
536 pr_err_ratelimited("%s: status bg bus overflow\n", __func__);
538 if (error_status1 & (1 << 18)) {
539 vfe_dev->stats->bf_overflow++;
540 pr_err_ratelimited("%s: status bf bus overflow\n", __func__);
542 if (error_status1 & (1 << 19)) {
543 vfe_dev->stats->awb_overflow++;
544 pr_err_ratelimited("%s: status awb bus overflow\n", __func__);
546 if (error_status1 & (1 << 20)) {
547 vfe_dev->stats->rs_overflow++;
548 pr_err_ratelimited("%s: status rs bus overflow\n", __func__);
550 if (error_status1 & (1 << 21)) {
551 vfe_dev->stats->cs_overflow++;
552 pr_err_ratelimited("%s: status cs bus overflow\n", __func__);
554 if (error_status1 & (1 << 22)) {
555 vfe_dev->stats->ihist_overflow++;
556 pr_err_ratelimited("%s: status ihist bus overflow\n", __func__);
558 if (error_status1 & (1 << 23)) {
559 vfe_dev->stats->skinbhist_overflow++;
560 pr_err_ratelimited("%s: status skin bhist bus overflow\n",
564 /* Update ab/ib values for any overflow that may have occured*/
565 if ((error_status1 >> 9) & 0x7FFF)
566 msm_isp_update_last_overflow_ab_ib(vfe_dev);
569 static void msm_vfe40_read_and_clear_irq_status(struct vfe_device *vfe_dev,
570 uint32_t *irq_status0, uint32_t *irq_status1)
572 *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
573 *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
575 * Ignore composite 2/3 irq which is used for dual VFE only
577 if (*irq_status0 & 0x6000000)
578 *irq_status0 &= ~(0x18000000);
579 msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
580 msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34);
581 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
582 if (*irq_status0 & 0x18000000) {
583 pr_err_ratelimited("%s: Protection triggered\n", __func__);
584 *irq_status0 &= ~(0x18000000);
587 *irq_status0 &= vfe_dev->irq0_mask;
588 *irq_status1 &= vfe_dev->irq1_mask;
590 (*irq_status0 == msm_camera_io_r(vfe_dev->vfe_base + 0x38))) {
591 msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
592 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
595 if (*irq_status1 & (1 << 0)) {
596 vfe_dev->error_info.camif_status =
597 msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
598 msm_vfe40_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
601 if (*irq_status1 & (1 << 7))
602 vfe_dev->error_info.violation_status |=
603 msm_camera_io_r(vfe_dev->vfe_base + 0x48);
607 static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
608 uint32_t *irq_status0, uint32_t *irq_status1)
610 *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
611 *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
614 static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
615 uint32_t irq_status0, uint32_t irq_status1,
616 struct msm_isp_timestamp *ts)
618 enum msm_vfe_input_src i;
620 uint8_t reg_updated = 0;
623 if (!(irq_status0 & 0xF0))
625 /* Shift status bits so that PIX REG UPDATE is 1st bit */
626 shift_irq = ((irq_status0 & 0xF0) >> 4);
627 for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
628 if (shift_irq & BIT(i)) {
629 reg_updated |= BIT(i);
630 ISP_DBG("%s REG_UPDATE IRQ %x\n", __func__,
634 msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
636 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
637 MSM_ISP_COMP_IRQ_REG_UPD, ts);
638 msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
639 MSM_ISP_COMP_IRQ_REG_UPD);
640 if (vfe_dev->axi_data.src_info[i].stream_count
642 vfe_dev->axi_data.src_info[i].
643 raw_stream_count == 0 &&
644 vfe_dev->axi_data.src_info[i].active)
645 vfe_dev->hw_info->vfe_ops.core_ops.
646 reg_update(vfe_dev, i);
651 msm_isp_increment_frame_id(vfe_dev, i, ts);
652 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
653 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
654 MSM_ISP_COMP_IRQ_REG_UPD, ts);
656 * Reg Update is pseudo SOF for RDI,
657 * so request every frame
659 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
661 /* reg upd is also epoch for RDI */
662 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
663 MSM_ISP_COMP_IRQ_EPOCH, ts);
666 pr_err("%s: Error case\n", __func__);
672 spin_lock_irqsave(&vfe_dev->reg_update_lock, flags);
673 if (reg_updated & BIT(VFE_PIX_0))
674 vfe_dev->reg_updated = 1;
676 vfe_dev->reg_update_requested &= ~reg_updated;
677 spin_unlock_irqrestore(&vfe_dev->reg_update_lock, flags);
680 static void msm_vfe40_reg_update(struct vfe_device *vfe_dev,
681 enum msm_vfe_input_src frame_src)
683 uint32_t update_mask = 0;
686 /* This HW supports upto VFE_RAW_2 */
687 if (frame_src > VFE_RAW_2 && frame_src != VFE_SRC_MAX) {
688 pr_err("%s Error case\n", __func__);
693 * If frame_src == VFE_SRC_MAX request reg_update on all
696 if (frame_src == VFE_SRC_MAX)
699 update_mask = BIT((uint32_t)frame_src);
700 ISP_DBG("%s update_mask %x\n", __func__, update_mask);
702 spin_lock_irqsave(&vfe_dev->reg_update_lock, flags);
703 vfe_dev->axi_data.src_info[VFE_PIX_0].reg_update_frame_id =
704 vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
705 vfe_dev->reg_update_requested |= update_mask;
706 vfe_dev->common_data->dual_vfe_res->reg_update_mask[vfe_dev->pdev->id] =
707 vfe_dev->reg_update_requested;
708 if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) &&
709 ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) {
710 if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) {
711 pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__);
712 spin_unlock_irqrestore(&vfe_dev->reg_update_lock,
716 msm_camera_io_w_mb(update_mask,
717 vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]
719 msm_camera_io_w_mb(update_mask,
720 vfe_dev->vfe_base + 0x378);
721 } else if (!vfe_dev->is_split ||
722 ((frame_src == VFE_PIX_0) &&
723 (vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
724 (vfe_dev->axi_data.src_info[VFE_PIX_0].
725 raw_stream_count == 0)) ||
726 (frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
727 msm_camera_io_w_mb(update_mask,
728 vfe_dev->vfe_base + 0x378);
730 spin_unlock_irqrestore(&vfe_dev->reg_update_lock, flags);
733 static void msm_vfe40_process_epoch_irq(struct vfe_device *vfe_dev,
734 uint32_t irq_status0, uint32_t irq_status1,
735 struct msm_isp_timestamp *ts)
737 if (!(irq_status0 & 0xc))
740 if (irq_status0 & BIT(2)) {
741 ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
742 msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
743 MSM_ISP_COMP_IRQ_EPOCH, ts);
744 msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
745 MSM_ISP_COMP_IRQ_EPOCH);
746 msm_isp_update_error_frame_count(vfe_dev);
747 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
748 if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
749 && vfe_dev->axi_data.src_info[VFE_PIX_0].
751 ISP_DBG("%s: SOF IRQ\n", __func__);
752 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
753 msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
754 MSM_ISP_COMP_IRQ_REG_UPD, ts);
755 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
761 static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev,
762 uint32_t first_start, uint32_t blocking_call)
767 spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
768 init_completion(&vfe_dev->reset_complete);
769 spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
772 msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
774 msm_camera_io_w_mb(0x1EF, vfe_dev->vfe_base + 0xC);
775 msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
776 msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
777 msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
778 vfe_dev->hw_info->vfe_ops.axi_ops.
779 reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0003FFFF);
784 rc = wait_for_completion_timeout(
785 &vfe_dev->reset_complete, msecs_to_jiffies(50));
790 static void msm_vfe40_axi_reload_wm(struct vfe_device *vfe_dev,
791 void __iomem *vfe_base, uint32_t reload_mask)
793 msm_camera_io_w_mb(reload_mask, vfe_base + 0x4C);
796 static void msm_vfe40_axi_update_cgc_override(struct vfe_device *vfe_dev,
797 uint8_t wm_idx, uint8_t enable)
801 /* Change CGC override */
802 val = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
804 val |= (1 << wm_idx);
806 val &= ~(1 << wm_idx);
807 msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x974);
810 static void msm_vfe40_axi_enable_wm(void __iomem *vfe_base,
811 uint8_t wm_idx, uint8_t enable)
814 val = msm_camera_io_r(vfe_base + VFE40_WM_BASE(wm_idx));
819 msm_camera_io_w_mb(val,
820 vfe_base + VFE40_WM_BASE(wm_idx));
823 static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
824 struct msm_vfe_axi_stream *stream_info)
826 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
827 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
828 uint32_t comp_mask, comp_mask_index;
830 comp_mask_index = stream_info->comp_mask_index[vfe_idx];
832 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
833 comp_mask &= ~(0x7F << (comp_mask_index * 8));
834 comp_mask |= (axi_data->composite_info[comp_mask_index].
835 stream_composite_mask << (comp_mask_index * 8));
837 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
838 msm_vfe40_config_irq(vfe_dev, 1 << (comp_mask_index + 25), 0,
842 static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
843 struct msm_vfe_axi_stream *stream_info)
845 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
846 uint32_t comp_mask, comp_mask_index;
848 comp_mask_index = stream_info->comp_mask_index[vfe_idx];
849 vfe_dev->irq0_mask &= ~BIT(27);
851 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
852 comp_mask &= ~(0x7F << (comp_mask_index * 8));
854 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
855 msm_vfe40_config_irq(vfe_dev, (1 << (comp_mask_index + 25)), 0,
856 MSM_ISP_IRQ_DISABLE);
859 static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
860 struct msm_vfe_axi_stream *stream_info)
862 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
864 msm_vfe40_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
868 static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
869 struct msm_vfe_axi_stream *stream_info)
871 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
873 vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[vfe_idx][0] + 8));
874 msm_vfe40_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
875 0, MSM_ISP_IRQ_DISABLE);
878 static void msm_vfe40_cfg_framedrop(struct vfe_device *vfe_dev,
879 struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
880 uint32_t framedrop_period)
882 void __iomem *vfe_base = vfe_dev->vfe_base;
884 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
886 for (i = 0; i < stream_info->num_planes; i++) {
887 msm_camera_io_w(framedrop_pattern, vfe_base +
888 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
889 temp = msm_camera_io_r(vfe_base +
890 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
892 msm_camera_io_w(temp | (framedrop_period - 1) << 2,
893 vfe_base + VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
896 msm_camera_io_w_mb(0x1, vfe_base + 0x378);
899 static void msm_vfe40_clear_framedrop(struct vfe_device *vfe_dev,
900 struct msm_vfe_axi_stream *stream_info)
903 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
905 for (i = 0; i < stream_info->num_planes; i++)
906 msm_camera_io_w(0, vfe_dev->vfe_base +
907 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
910 static int32_t msm_vfe40_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
925 pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
931 static int32_t msm_vfe40_convert_io_fmt_to_reg(
932 enum msm_isp_pack_fmt pack_format, uint32_t *pack_reg)
936 switch (pack_format) {
956 pr_err("%s: invalid pack fmt %d!\n", __func__, pack_format);
962 static int32_t msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
963 enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
966 int bpp = 0, read_bpp = 0;
967 enum msm_isp_pack_fmt pack_fmt = 0, read_pack_fmt = 0;
968 uint32_t bpp_reg = 0, pack_reg = 0;
969 uint32_t read_bpp_reg = 0, read_pack_reg = 0;
970 uint32_t io_format_reg = 0; /*io format register bit*/
972 io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
973 if ((stream_src < RDI_INTF_0) &&
974 (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux ==
976 read_bpp = msm_isp_get_bit_per_pixel(
977 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
978 rc = msm_vfe40_convert_bpp_to_reg(read_bpp, &read_bpp_reg);
980 pr_err("%s: convert_bpp_to_reg err! in_bpp %d rc %d\n",
981 __func__, read_bpp, rc);
984 read_pack_fmt = msm_isp_get_pack_format(
985 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
986 rc = msm_vfe40_convert_io_fmt_to_reg(
987 read_pack_fmt, &read_pack_reg);
989 pr_err("%s: convert_io_fmt_to_reg err! rc = %d\n",
993 /*use input format(v4l2_pix_fmt) to get pack format*/
994 io_format_reg &= 0xFFC8FFFF;
995 io_format_reg |= (read_bpp_reg << 20 | read_pack_reg << 16);
998 bpp = msm_isp_get_bit_per_pixel(io_format);
999 rc = msm_vfe40_convert_bpp_to_reg(bpp, &bpp_reg);
1001 pr_err("%s: convert_bpp_to_reg err! bpp %d rc = %d\n",
1006 switch (stream_src) {
1008 case PIX_VIEWFINDER:
1010 io_format_reg &= 0xFFFFCFFF;
1011 io_format_reg |= bpp_reg << 12;
1014 /*use output format(v4l2_pix_fmt) to get pack format*/
1015 pack_fmt = msm_isp_get_pack_format(io_format);
1016 rc = msm_vfe40_convert_io_fmt_to_reg(pack_fmt, &pack_reg);
1018 pr_err("%s: convert_io_fmt_to_reg err! rc = %d\n",
1022 io_format_reg &= 0xFFFFFFC8;
1023 io_format_reg |= bpp_reg << 4 | pack_reg;
1029 pr_err("%s: Invalid stream source\n", __func__);
1032 msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
1036 static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev,
1040 uint32_t bufq_handle = 0;
1041 struct msm_isp_buffer *buf = NULL;
1042 struct msm_vfe_fetch_eng_start *fe_cfg = arg;
1043 struct msm_isp_buffer_mapped_info mapped_info;
1045 if (vfe_dev->fetch_engine_info.is_busy == 1) {
1046 pr_err("%s: fetch engine busy\n", __func__);
1049 memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
1050 /* There is other option of passing buffer address from user,
1051 in such case, driver needs to map the buffer and use it*/
1052 vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
1053 vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
1054 vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
1055 vfe_dev->fetch_engine_info.fd = fe_cfg->fd;
1057 if (!fe_cfg->offline_mode) {
1058 bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
1059 vfe_dev->buf_mgr, fe_cfg->session_id,
1061 vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
1063 mutex_lock(&vfe_dev->buf_mgr->lock);
1064 rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
1065 vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
1066 if (rc < 0 || !buf) {
1067 pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
1069 mutex_unlock(&vfe_dev->buf_mgr->lock);
1072 mapped_info = buf->mapped_info[0];
1073 buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
1074 mutex_unlock(&vfe_dev->buf_mgr->lock);
1076 rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
1077 &mapped_info, fe_cfg->fd);
1079 pr_err("%s: can not map buffer\n", __func__);
1083 vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
1084 vfe_dev->fetch_engine_info.is_busy = 1;
1086 msm_camera_io_w(mapped_info.paddr, vfe_dev->vfe_base + 0x228);
1087 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
1089 msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
1090 msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);
1092 ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id);
1096 static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
1100 uint32_t bufq_handle = 0;
1101 struct msm_isp_buffer *buf = NULL;
1102 struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg;
1103 struct msm_isp_buffer_mapped_info mapped_info;
1105 if (vfe_dev->fetch_engine_info.is_busy == 1) {
1106 pr_err("%s: fetch engine busy\n", __func__);
1109 memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
1110 /* There is other option of passing buffer address from user,
1111 * in such case, driver needs to map the buffer and use it
1113 vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
1114 vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
1115 vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
1116 vfe_dev->fetch_engine_info.fd = fe_cfg->fd;
1118 if (!fe_cfg->offline_mode) {
1119 bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
1120 vfe_dev->buf_mgr, fe_cfg->session_id,
1122 vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
1124 mutex_lock(&vfe_dev->buf_mgr->lock);
1125 rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
1126 vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
1127 if (rc < 0 || !buf) {
1128 pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
1130 mutex_unlock(&vfe_dev->buf_mgr->lock);
1133 mapped_info = buf->mapped_info[0];
1134 buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
1135 mutex_unlock(&vfe_dev->buf_mgr->lock);
1137 rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
1138 &mapped_info, fe_cfg->fd);
1140 pr_err("%s: can not map buffer\n", __func__);
1144 vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
1145 vfe_dev->fetch_engine_info.is_busy = 1;
1147 msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset,
1148 vfe_dev->vfe_base + 0x228);
1150 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
1152 msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
1153 msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);
1155 ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id);
1159 static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev,
1160 struct msm_vfe_pix_cfg *pix_cfg)
1162 uint32_t x_size_word;
1164 uint32_t main_unpack_pattern = 0;
1165 struct msm_vfe_fetch_engine_cfg *fe_cfg = NULL;
1167 if (pix_cfg->input_mux != EXTERNAL_READ) {
1168 pr_err("%s: Invalid mux configuration - mux: %d",
1169 __func__, pix_cfg->input_mux);
1173 fe_cfg = &pix_cfg->fetch_engine_cfg;
1174 pr_debug("%s: fetch_dbg wd x ht buf = %d x %d, fe = %d x %d\n",
1175 __func__, fe_cfg->buf_width, fe_cfg->buf_height,
1176 fe_cfg->fetch_width, fe_cfg->fetch_height);
1178 vfe_dev->hw_info->vfe_ops.axi_ops.update_cgc_override(vfe_dev,
1179 VFE40_BUS_RD_CGC_OVERRIDE_BIT, 1);
1181 temp = msm_camera_io_r(vfe_dev->vfe_base + 0x50);
1184 msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50);
1186 msm_vfe40_config_irq(vfe_dev, (1 << 24), 0,
1187 MSM_ISP_IRQ_ENABLE);
1189 msm_camera_io_w((fe_cfg->fetch_height - 1),
1190 vfe_dev->vfe_base + 0x238);
1192 /* need to update to use formulae to calculate X_SIZE_WORD*/
1193 x_size_word = msm_isp_cal_word_per_line(
1194 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format,
1197 msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x23C);
1199 x_size_word = msm_isp_cal_word_per_line(
1200 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format,
1201 fe_cfg->fetch_width);
1203 temp = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
1204 temp |= 2 << 16 | pix_cfg->pixel_pattern;
1205 msm_camera_io_w(temp, vfe_dev->vfe_base + 0x1C);
1207 if (vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
1208 msm_camera_io_w(x_size_word << 17 |
1209 (fe_cfg->buf_height-1) << 4 |
1210 VFE40_FETCH_BURST_LEN,
1211 vfe_dev->vfe_base + 0x240);
1212 msm_camera_io_w(0 << 29 | 2 << 26 |
1213 (fe_cfg->buf_width - 1) << 13 |
1214 (fe_cfg->buf_height - 1),
1215 vfe_dev->vfe_base + 0x244);
1217 msm_camera_io_w(x_size_word << 16 |
1218 (fe_cfg->buf_height-1) << 4 |
1219 VFE40_FETCH_BURST_LEN,
1220 vfe_dev->vfe_base + 0x240);
1221 msm_camera_io_w(0 << 28 | 2 << 25 |
1222 (fe_cfg->buf_width - 1) << 12 |
1223 (fe_cfg->buf_height - 1),
1224 vfe_dev->vfe_base + 0x244);
1227 /* need to use formulae to calculate MAIN_UNPACK_PATTERN*/
1228 switch (vfe_dev->axi_data.src_info[VFE_PIX_0].input_format) {
1229 case V4L2_PIX_FMT_P16BGGR10:
1230 case V4L2_PIX_FMT_P16GBRG10:
1231 case V4L2_PIX_FMT_P16GRBG10:
1232 case V4L2_PIX_FMT_P16RGGB10:
1233 main_unpack_pattern = 0xB210;
1236 main_unpack_pattern = 0xF6543210;
1239 msm_camera_io_w(main_unpack_pattern,
1240 vfe_dev->vfe_base + 0x248);
1241 msm_camera_io_w(0xF, vfe_dev->vfe_base + 0x264);
1246 static void msm_vfe40_cfg_testgen(struct vfe_device *vfe_dev,
1247 struct msm_vfe_testgen_cfg *testgen_cfg)
1249 uint32_t bit_per_pixel = 0;
1250 uint32_t bpp_reg = 0;
1251 uint32_t bayer_pix_pattern_reg = 0;
1252 uint32_t unicolorbar_reg = 0;
1253 uint32_t unicolor_enb = 0;
1255 bit_per_pixel = msm_isp_get_bit_per_pixel(
1256 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
1258 switch (bit_per_pixel) {
1272 pr_err("%s: invalid bpp %d\n", __func__, bit_per_pixel);
1276 msm_camera_io_w(bpp_reg << 16 | testgen_cfg->burst_num_frame,
1277 vfe_dev->vfe_base + 0x940);
1279 msm_camera_io_w(((testgen_cfg->lines_per_frame - 1) << 16) |
1280 (testgen_cfg->pixels_per_line - 1), vfe_dev->vfe_base + 0x944);
1282 msm_camera_io_w(testgen_cfg->h_blank, vfe_dev->vfe_base + 0x958);
1284 msm_camera_io_w((1 << 16) | testgen_cfg->v_blank,
1285 vfe_dev->vfe_base + 0x95C);
1287 switch (testgen_cfg->pixel_bayer_pattern) {
1288 case ISP_BAYER_RGRGRG:
1289 bayer_pix_pattern_reg = 0x0;
1291 case ISP_BAYER_GRGRGR:
1292 bayer_pix_pattern_reg = 0x1;
1294 case ISP_BAYER_BGBGBG:
1295 bayer_pix_pattern_reg = 0x10;
1297 case ISP_BAYER_GBGBGB:
1298 bayer_pix_pattern_reg = 0x11;
1301 pr_err("%s: invalid pix pattern %d\n",
1302 __func__, bit_per_pixel);
1306 if (testgen_cfg->color_bar_pattern == COLOR_BAR_8_COLOR) {
1310 switch (testgen_cfg->color_bar_pattern) {
1311 case UNICOLOR_WHITE:
1312 unicolorbar_reg = 0x0;
1314 case UNICOLOR_YELLOW:
1315 unicolorbar_reg = 0x1;
1318 unicolorbar_reg = 0x10;
1320 case UNICOLOR_GREEN:
1321 unicolorbar_reg = 0x11;
1323 case UNICOLOR_MAGENTA:
1324 unicolorbar_reg = 0x100;
1327 unicolorbar_reg = 0x101;
1330 unicolorbar_reg = 0x110;
1332 case UNICOLOR_BLACK:
1333 unicolorbar_reg = 0x111;
1336 pr_err("%s: invalid colorbar %d\n",
1337 __func__, testgen_cfg->color_bar_pattern);
1341 msm_camera_io_w((testgen_cfg->rotate_period << 8) |
1342 (bayer_pix_pattern_reg << 6) | (unicolor_enb << 4) |
1343 (unicolorbar_reg), vfe_dev->vfe_base + 0x968);
1346 static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
1347 struct msm_vfe_pix_cfg *pix_cfg)
1349 uint16_t first_pixel, last_pixel, first_line, last_line;
1350 uint16_t epoch_line1;
1351 struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
1352 uint32_t val, subsample_period, subsample_pattern;
1353 struct msm_vfe_camif_subsample_cfg *subsample_cfg =
1354 &pix_cfg->camif_cfg.subsample_cfg;
1355 uint16_t bus_sub_en = 0;
1357 vfe_dev->dual_vfe_enable = camif_cfg->is_split;
1359 msm_camera_io_w(pix_cfg->input_mux << 16 | pix_cfg->pixel_pattern,
1360 vfe_dev->vfe_base + 0x1C);
1362 first_pixel = camif_cfg->first_pixel;
1363 last_pixel = camif_cfg->last_pixel;
1364 first_line = camif_cfg->first_line;
1365 last_line = camif_cfg->last_line;
1366 epoch_line1 = camif_cfg->epoch_line1;
1368 if ((epoch_line1 <= 0) || (epoch_line1 > last_line))
1369 epoch_line1 = last_line - 50;
1371 if ((last_line - epoch_line1) > 100)
1372 epoch_line1 = last_line - 100;
1374 subsample_period = camif_cfg->subsample_cfg.irq_subsample_period;
1375 subsample_pattern = camif_cfg->subsample_cfg.irq_subsample_pattern;
1377 msm_camera_io_w(camif_cfg->lines_per_frame << 16 |
1378 camif_cfg->pixels_per_line, vfe_dev->vfe_base + 0x300);
1380 msm_camera_io_w(first_pixel << 16 | last_pixel,
1381 vfe_dev->vfe_base + 0x304);
1383 msm_camera_io_w(first_line << 16 | last_line,
1384 vfe_dev->vfe_base + 0x308);
1386 /*configure EPOCH0: 20 lines, and
1387 * configure EPOCH1: epoch_line1 before EOF
1389 msm_camera_io_w_mb(0x140000 | epoch_line1,
1390 vfe_dev->vfe_base + 0x318);
1391 pr_debug("%s:%d: epoch_line1: %d\n",
1392 __func__, __LINE__, epoch_line1);
1393 if (subsample_period && subsample_pattern) {
1394 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1396 val = (subsample_period - 1) << 16;
1397 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1398 ISP_DBG("%s:camif PERIOD %x PATTERN %x\n",
1399 __func__, subsample_period, subsample_pattern);
1401 val = subsample_pattern;
1402 msm_camera_io_w(val, vfe_dev->vfe_base + 0x314);
1404 msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x314);
1406 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2E8);
1407 val |= camif_cfg->camif_input;
1408 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2E8);
1410 if (subsample_cfg->pixel_skip || subsample_cfg->line_skip) {
1412 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1414 val = val | bus_sub_en << 5;
1415 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1416 subsample_cfg->pixel_skip &= 0x0000FFFF;
1417 subsample_cfg->line_skip &= 0x0000FFFF;
1418 msm_camera_io_w((subsample_cfg->line_skip << 16) |
1419 subsample_cfg->pixel_skip,
1420 vfe_dev->vfe_base + 0x30C);
1421 if (subsample_cfg->first_pixel ||
1422 subsample_cfg->last_pixel ||
1423 subsample_cfg->first_line ||
1424 subsample_cfg->last_line) {
1426 subsample_cfg->first_pixel << 16 |
1427 subsample_cfg->last_pixel,
1428 vfe_dev->vfe_base + 0x8A4);
1430 subsample_cfg->first_line << 16 |
1431 subsample_cfg->last_line,
1432 vfe_dev->vfe_base + 0x8A8);
1433 val = msm_camera_io_r(
1434 vfe_dev->vfe_base + 0x2F8);
1436 msm_camera_io_w(val,
1437 vfe_dev->vfe_base + 0x2F8);
1440 ISP_DBG("%s:camif raw op fmt %d\n",
1441 __func__, subsample_cfg->output_format);
1442 /* Pdaf output will be sent in PLAIN16 format*/
1443 val = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
1444 switch (subsample_cfg->output_format) {
1448 case CAMIF_PLAIN_16:
1451 case CAMIF_MIPI_RAW:
1454 case CAMIF_QCOM_RAW:
1458 msm_camera_io_w(val, vfe_dev->vfe_base + 0x54);
1462 static void msm_vfe40_cfg_input_mux(struct vfe_device *vfe_dev,
1463 struct msm_vfe_pix_cfg *pix_cfg)
1465 uint32_t core_cfg = 0;
1468 core_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
1469 core_cfg &= 0xFFFCFFFF;
1471 switch (pix_cfg->input_mux) {
1473 core_cfg |= 0x0 << 16;
1474 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1475 msm_vfe40_cfg_camif(vfe_dev, pix_cfg);
1478 /* Change CGC override */
1479 val = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
1481 msm_camera_io_w(val, vfe_dev->vfe_base + 0x974);
1483 /* CAMIF and TESTGEN will both go thorugh CAMIF*/
1484 core_cfg |= 0x1 << 16;
1485 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1486 msm_vfe40_cfg_camif(vfe_dev, pix_cfg);
1487 msm_vfe40_cfg_testgen(vfe_dev, &pix_cfg->testgen_cfg);
1490 core_cfg |= 0x2 << 16;
1491 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1492 msm_vfe40_cfg_fetch_engine(vfe_dev, pix_cfg);
1495 pr_err("%s: Unsupported input mux %d\n",
1496 __func__, pix_cfg->input_mux);
1502 static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
1503 enum msm_isp_camif_update_state update_state)
1506 bool bus_en, vfe_en;
1507 if (update_state == NO_UPDATE)
1510 if (update_state == ENABLE_CAMIF) {
1511 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x30);
1512 msm_camera_io_w_mb(0x81, vfe_dev->vfe_base + 0x34);
1513 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
1514 msm_vfe40_config_irq(vfe_dev, 0xFF, 0x81,
1515 MSM_ISP_IRQ_ENABLE);
1518 ((vfe_dev->axi_data.
1519 src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
1521 ((vfe_dev->axi_data.
1522 src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
1523 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1525 val = val | bus_en << 7 | vfe_en << 6;
1526 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1528 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1529 msm_camera_io_w(1, vfe_dev->vfe_base + 0x93C);
1530 msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x2F4);
1531 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
1532 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
1533 } else if (update_state == DISABLE_CAMIF ||
1534 DISABLE_CAMIF_IMMEDIATELY == update_state) {
1537 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1538 update_state = DISABLE_CAMIF;
1539 msm_vfe40_config_irq(vfe_dev, 0, 0x81,
1540 MSM_ISP_IRQ_DISABLE);
1541 val = msm_camera_io_r(vfe_dev->vfe_base + 0x464);
1542 /* disable danger signal */
1543 msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464);
1544 msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
1545 vfe_dev->vfe_base + 0x2F4);
1546 if (readl_poll_timeout_atomic(vfe_dev->vfe_base + 0x31C,
1547 poll_val, poll_val & 0x80000000, 1000, 2000000))
1548 pr_err("%s: camif disable failed %x\n",
1549 __func__, poll_val);
1550 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
1552 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1553 msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C);
1554 msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
1555 msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34);
1556 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
1557 msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask,
1563 static void msm_vfe40_cfg_rdi_reg(
1564 struct vfe_device *vfe_dev, struct msm_vfe_rdi_cfg *rdi_cfg,
1565 enum msm_vfe_input_src input_src)
1567 uint8_t rdi = input_src - VFE_RAW_0;
1568 uint32_t rdi_reg_cfg;
1569 rdi_reg_cfg = msm_camera_io_r(
1570 vfe_dev->vfe_base + VFE40_RDI_BASE(0));
1571 rdi_reg_cfg &= ~(BIT(16 + rdi));
1572 rdi_reg_cfg |= rdi_cfg->frame_based << (16 + rdi);
1573 msm_camera_io_w(rdi_reg_cfg,
1574 vfe_dev->vfe_base + VFE40_RDI_BASE(0));
1576 rdi_reg_cfg = msm_camera_io_r(
1577 vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
1578 rdi_reg_cfg &= 0x70003;
1579 rdi_reg_cfg |= (rdi * 3) << 28 | rdi_cfg->cid << 4 | 0x4;
1581 rdi_reg_cfg, vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
1584 static void msm_vfe40_axi_cfg_wm_reg(
1585 struct vfe_device *vfe_dev,
1586 struct msm_vfe_axi_stream *stream_info,
1590 uint32_t burst_len, wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION;
1591 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1594 wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
1596 if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
1597 vfe_dev->vfe_hw_version == VFE40_8939_VERSION) {
1598 burst_len = VFE40_BURST_LEN_8916_VERSION;
1599 wm_bit_shift = VFE40_WM_BIT_SHIFT;
1600 } else if (vfe_dev->vfe_hw_version == VFE40_8952_VERSION) {
1601 burst_len = VFE40_BURST_LEN_8952_VERSION;
1602 wm_bit_shift = VFE40_WM_BIT_SHIFT;
1603 } else if (vfe_dev->vfe_hw_version == VFE40_8976_VERSION ||
1604 vfe_dev->vfe_hw_version == VFE40_8937_VERSION ||
1605 vfe_dev->vfe_hw_version == VFE40_8917_VERSION ||
1606 vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
1607 burst_len = VFE40_BURST_LEN_8952_VERSION;
1608 wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION;
1610 burst_len = VFE40_BURST_LEN;
1613 if (!stream_info->frame_based) {
1614 msm_camera_io_w(0x0, vfe_dev->vfe_base + wm_base);
1617 ((msm_isp_cal_word_per_line(
1618 stream_info->output_format,
1619 stream_info->plane_cfg[vfe_idx][plane_idx].
1620 output_width)+1)/2 - 1) << 16 |
1621 (stream_info->plane_cfg[vfe_idx][plane_idx].
1623 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
1627 msm_isp_cal_word_per_line(stream_info->output_format,
1628 stream_info->plane_cfg[vfe_idx][
1629 plane_idx].output_stride) << 16 |
1630 (stream_info->plane_cfg[vfe_idx][
1631 plane_idx].output_height - 1) << wm_bit_shift |
1633 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1635 msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
1637 msm_isp_cal_word_per_line(stream_info->output_format,
1638 stream_info->plane_cfg[vfe_idx][
1639 plane_idx].output_width) << 16 |
1640 (stream_info->plane_cfg[vfe_idx][
1641 plane_idx].output_height - 1) << 4 |
1643 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1646 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1647 msm_camera_io_w(0xFFFFFFFF,
1648 vfe_dev->vfe_base + wm_base + 0x20);
1649 /* TD: Add IRQ subsample pattern */
1653 static void msm_vfe40_axi_clear_wm_reg(
1654 struct vfe_device *vfe_dev,
1655 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
1658 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1661 wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
1663 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
1665 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
1667 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1668 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1669 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x20);
1673 static void msm_vfe40_axi_cfg_wm_xbar_reg(
1674 struct vfe_device *vfe_dev,
1675 struct msm_vfe_axi_stream *stream_info,
1678 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1679 struct msm_vfe_axi_plane_cfg *plane_cfg;
1681 uint32_t xbar_cfg = 0;
1682 uint32_t xbar_reg_cfg = 0;
1684 plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
1685 wm = stream_info->wm[vfe_idx][plane_idx];
1687 switch (stream_info->stream_src) {
1689 case PIX_VIEWFINDER: {
1690 if (plane_cfg->output_plane_format != CRCB_PLANE &&
1691 plane_cfg->output_plane_format != CBCR_PLANE) {
1692 /*SINGLE_STREAM_SEL*/
1693 xbar_cfg |= plane_cfg->output_plane_format << 8;
1695 switch (stream_info->output_format) {
1696 case V4L2_PIX_FMT_NV12:
1697 case V4L2_PIX_FMT_NV14:
1698 case V4L2_PIX_FMT_NV16:
1699 case V4L2_PIX_FMT_NV24:
1700 xbar_cfg |= 0x3 << 4; /*PAIR_STREAM_SWAP_CTRL*/
1703 xbar_cfg |= 0x1 << 1; /*PAIR_STREAM_EN*/
1705 if (stream_info->stream_src == PIX_VIEWFINDER)
1706 xbar_cfg |= 0x1; /*VIEW_STREAM_EN*/
1725 pr_err("%s: Invalid stream src\n", __func__);
1729 msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1730 xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
1731 xbar_reg_cfg |= (xbar_cfg << VFE40_XBAR_SHIFT(wm));
1732 msm_camera_io_w(xbar_reg_cfg,
1733 vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1737 static void msm_vfe40_axi_clear_wm_xbar_reg(
1738 struct vfe_device *vfe_dev,
1739 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
1741 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1743 uint32_t xbar_reg_cfg = 0;
1745 wm = stream_info->wm[vfe_idx][plane_idx];
1748 msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1749 xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
1750 msm_camera_io_w(xbar_reg_cfg,
1751 vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1754 static void msm_vfe40_read_wm_ping_pong_addr(
1755 struct vfe_device *vfe_dev)
1757 msm_camera_io_dump(vfe_dev->vfe_base +
1758 (VFE40_WM_BASE(0) & 0xFFFFFFF0), 0x200, 1);
1761 static void msm_vfe40_update_ping_pong_addr(
1762 void __iomem *vfe_base,
1763 uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr,
1766 uint32_t paddr32 = (paddr & 0xFFFFFFFF);
1767 msm_camera_io_w(paddr32, vfe_base +
1768 VFE40_PING_PONG_BASE(wm_idx, pingpong_bit));
1771 static void msm_vfe40_set_halt_restart_mask(struct vfe_device *vfe_dev)
1773 msm_vfe40_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET);
1776 static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
1780 enum msm_vfe_input_src i;
1781 struct msm_isp_timestamp ts;
1782 unsigned long flags;
1784 /* Keep only halt and restart mask */
1785 msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
1788 msm_isp_get_timestamp(&ts, vfe_dev);
1789 /* if any stream is waiting for update, signal complete */
1790 for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
1791 msm_isp_axi_stream_update(vfe_dev, i, &ts);
1792 msm_isp_axi_stream_update(vfe_dev, i, &ts);
1795 msm_isp_stats_stream_update(vfe_dev);
1796 msm_isp_stats_stream_update(vfe_dev);
1799 spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
1800 init_completion(&vfe_dev->halt_complete);
1801 spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
1802 /* Halt AXI Bus Bridge */
1803 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
1804 rc = wait_for_completion_interruptible_timeout(
1805 &vfe_dev->halt_complete, msecs_to_jiffies(500));
1807 pr_err("%s:VFE%d halt timeout rc=%d\n", __func__,
1808 vfe_dev->pdev->id, rc);
1810 /* Halt AXI Bus Bridge */
1811 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
1817 static void msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
1818 uint32_t blocking, uint32_t enable_camif)
1820 msm_vfe40_config_irq(vfe_dev, vfe_dev->recovery_irq0_mask,
1821 vfe_dev->recovery_irq1_mask,
1822 MSM_ISP_IRQ_ENABLE);
1823 msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318);
1826 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
1828 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX);
1829 memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
1830 atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
1832 vfe_dev->hw_info->vfe_ops.core_ops.
1833 update_camif_state(vfe_dev, ENABLE_CAMIF);
1836 static uint32_t msm_vfe40_get_wm_mask(
1837 uint32_t irq_status0, uint32_t irq_status1)
1839 return (irq_status0 >> 8) & 0x7F;
1842 static uint32_t msm_vfe40_get_comp_mask(
1843 uint32_t irq_status0, uint32_t irq_status1)
1845 return (irq_status0 >> 25) & 0xF;
1848 static uint32_t msm_vfe40_get_pingpong_status(
1849 struct vfe_device *vfe_dev)
1851 return msm_camera_io_r(vfe_dev->vfe_base + 0x268);
1854 static int msm_vfe40_get_stats_idx(enum msm_isp_stats_type stats_type)
1856 switch (stats_type) {
1857 case MSM_ISP_STATS_BE:
1859 case MSM_ISP_STATS_BG:
1861 case MSM_ISP_STATS_BF:
1863 case MSM_ISP_STATS_AWB:
1865 case MSM_ISP_STATS_RS:
1867 case MSM_ISP_STATS_CS:
1869 case MSM_ISP_STATS_IHIST:
1871 case MSM_ISP_STATS_BHIST:
1874 pr_err("%s: Invalid stats type\n", __func__);
1879 static int msm_vfe40_stats_check_streams(
1880 struct msm_vfe_stats_stream *stream_info)
1885 static void msm_vfe40_stats_cfg_comp_mask(struct vfe_device *vfe_dev,
1886 uint32_t stats_mask, uint8_t request_comp_index, uint8_t enable)
1888 uint32_t comp_mask_reg, mask_bf_scale;
1889 atomic_t *stats_comp_mask;
1890 struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
1892 if (vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask < 1)
1895 if (request_comp_index >= MAX_NUM_STATS_COMP_MASK) {
1896 pr_err("%s: num of comp masks %d exceed max %d\n",
1897 __func__, request_comp_index,
1898 MAX_NUM_STATS_COMP_MASK);
1902 if (vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask >
1903 MAX_NUM_STATS_COMP_MASK) {
1904 pr_err("%s: num of comp masks %d exceed max %d\n",
1906 vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask,
1907 MAX_NUM_STATS_COMP_MASK);
1911 stats_mask = stats_mask & 0xFF;
1912 mask_bf_scale = stats_mask;
1914 stats_comp_mask = &stats_data->stats_comp_mask[request_comp_index];
1915 comp_mask_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x44);
1918 comp_mask_reg |= mask_bf_scale << (16 + request_comp_index * 8);
1919 atomic_set(stats_comp_mask, stats_mask |
1920 atomic_read(stats_comp_mask));
1921 msm_vfe40_config_irq(vfe_dev,
1922 1 << (request_comp_index + 29), 0,
1923 MSM_ISP_IRQ_ENABLE);
1925 if (!(atomic_read(stats_comp_mask) & stats_mask))
1927 atomic_set(stats_comp_mask,
1928 ~stats_mask & atomic_read(stats_comp_mask));
1929 comp_mask_reg &= ~(mask_bf_scale <<
1930 (16 + request_comp_index * 8));
1931 msm_vfe40_config_irq(vfe_dev,
1932 1 << (request_comp_index + 29), 0,
1933 MSM_ISP_IRQ_DISABLE);
1935 msm_camera_io_w(comp_mask_reg, vfe_dev->vfe_base + 0x44);
1937 ISP_DBG("%s: comp_mask_reg: %x comp mask0 %x mask1: %x\n",
1938 __func__, comp_mask_reg,
1939 atomic_read(&stats_data->stats_comp_mask[0]),
1940 atomic_read(&stats_data->stats_comp_mask[1]));
1945 static void msm_vfe40_stats_cfg_wm_irq_mask(
1946 struct vfe_device *vfe_dev,
1947 struct msm_vfe_stats_stream *stream_info)
1949 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1952 msm_vfe40_config_irq(vfe_dev,
1953 1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16), 0,
1954 MSM_ISP_IRQ_ENABLE);
1957 static void msm_vfe40_stats_clear_wm_irq_mask(
1958 struct vfe_device *vfe_dev,
1959 struct msm_vfe_stats_stream *stream_info)
1961 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1964 msm_vfe40_config_irq(vfe_dev,
1965 (1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16)), 0,
1966 MSM_ISP_IRQ_DISABLE);
1969 static void msm_vfe40_stats_cfg_wm_reg(
1970 struct vfe_device *vfe_dev,
1971 struct msm_vfe_stats_stream *stream_info)
1973 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1976 uint32_t stats_base;
1978 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
1979 stats_base = VFE40_STATS_BASE(stats_idx);
1981 msm_camera_io_w((stream_info->framedrop_period - 1) << 2,
1982 vfe_dev->vfe_base + stats_base + 0x8);
1983 /*WR_IRQ_FRAMEDROP_PATTERN*/
1984 msm_camera_io_w(stream_info->framedrop_pattern,
1985 vfe_dev->vfe_base + stats_base + 0x10);
1986 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1987 msm_camera_io_w(0xFFFFFFFF,
1988 vfe_dev->vfe_base + stats_base + 0x14);
1991 static void msm_vfe40_stats_clear_wm_reg(
1992 struct vfe_device *vfe_dev,
1993 struct msm_vfe_stats_stream *stream_info)
1995 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1999 uint32_t stats_base;
2001 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
2002 stats_base = VFE40_STATS_BASE(stats_idx);
2005 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x8);
2006 /*WR_IRQ_FRAMEDROP_PATTERN*/
2007 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x10);
2008 /*WR_IRQ_SUBSAMPLE_PATTERN*/
2009 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x14);
2012 static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
2016 uint32_t stats_burst_len;
2017 uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
2018 64, /*MSM_ISP_STATS_BE*/
2019 128, /*MSM_ISP_STATS_BG*/
2020 128, /*MSM_ISP_STATS_BF*/
2021 16, /*MSM_ISP_STATS_AWB*/
2022 8, /*MSM_ISP_STATS_RS*/
2023 16, /*MSM_ISP_STATS_CS*/
2024 16, /*MSM_ISP_STATS_IHIST*/
2025 16, /*MSM_ISP_STATS_BHIST*/
2028 if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
2029 vfe_dev->vfe_hw_version == VFE40_8939_VERSION ||
2030 vfe_dev->vfe_hw_version == VFE40_8937_VERSION ||
2031 vfe_dev->vfe_hw_version == VFE40_8917_VERSION ||
2032 vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
2033 stats_burst_len = VFE40_STATS_BURST_LEN_8916_VERSION;
2034 ub_offset = VFE40_UB_SIZE_8916;
2035 } else if (vfe_dev->vfe_hw_version == VFE40_8952_VERSION ||
2036 vfe_dev->vfe_hw_version == VFE40_8976_VERSION) {
2037 stats_burst_len = VFE40_STATS_BURST_LEN_8916_VERSION;
2038 ub_offset = VFE40_UB_SIZE_8952;
2040 stats_burst_len = VFE40_STATS_BURST_LEN;
2041 ub_offset = VFE40_UB_SIZE;
2044 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2045 ub_offset -= ub_size[i];
2046 msm_camera_io_w(stats_burst_len << 30 |
2047 ub_offset << 16 | (ub_size[i] - 1),
2048 vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
2052 static void msm_vfe40_stats_update_cgc_override(struct vfe_device *vfe_dev,
2053 uint32_t stats_mask, uint8_t enable)
2056 uint32_t module_cfg, cgc_mask = 0;
2058 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2059 if ((stats_mask >> i) & 0x1) {
2062 cgc_mask |= (1 << 8);
2065 cgc_mask |= (1 << 10);
2068 cgc_mask |= (1 << 9);
2070 case STATS_IDX_BHIST:
2071 cgc_mask |= (1 << 15);
2074 cgc_mask |= (1 << 11);
2077 cgc_mask |= (1 << 12);
2080 cgc_mask |= (1 << 13);
2082 case STATS_IDX_IHIST:
2083 cgc_mask |= (1 << 14);
2086 pr_err("%s: Invalid stats mask\n", __func__);
2093 module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
2095 module_cfg |= cgc_mask;
2097 module_cfg &= ~cgc_mask;
2098 msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x974);
2101 static bool msm_vfe40_is_module_cfg_lock_needed(
2102 uint32_t reg_offset)
2104 if (reg_offset == 0x18)
2110 static void msm_vfe40_stats_enable_module(struct vfe_device *vfe_dev,
2111 uint32_t stats_mask, uint8_t enable)
2114 uint32_t module_cfg, module_cfg_mask = 0;
2115 unsigned long flags;
2117 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2118 if ((stats_mask >> i) & 0x1) {
2126 module_cfg_mask |= 1 << (5 + i);
2129 module_cfg_mask |= 1 << 15;
2132 module_cfg_mask |= 1 << 18;
2135 pr_err("%s: Invalid stats mask\n", __func__);
2142 * For vfe40 stats and other modules share module_cfg register.
2143 * Hence need to Grab lock.
2145 spin_lock_irqsave(&vfe_dev->shared_data_lock, flags);
2146 module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x18);
2148 module_cfg |= module_cfg_mask;
2150 module_cfg &= ~module_cfg_mask;
2151 msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x18);
2152 spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
2155 static void msm_vfe40_stats_update_ping_pong_addr(
2156 struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
2157 uint32_t pingpong_status, dma_addr_t paddr, uint32_t buf_sz)
2159 void __iomem *vfe_base = vfe_dev->vfe_base;
2160 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
2162 uint32_t paddr32 = (paddr & 0xFFFFFFFF);
2165 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
2166 msm_camera_io_w(paddr32, vfe_base +
2167 VFE40_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
2170 static uint32_t msm_vfe40_stats_get_wm_mask(
2171 uint32_t irq_status0, uint32_t irq_status1)
2173 return (irq_status0 >> 16) & 0xFF;
2176 static uint32_t msm_vfe40_stats_get_comp_mask(
2177 uint32_t irq_status0, uint32_t irq_status1)
2179 return (irq_status0 >> 29) & 0x3;
2182 static uint32_t msm_vfe40_stats_get_frame_id(
2183 struct vfe_device *vfe_dev)
2185 return vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
2188 static void msm_vfe40_get_error_mask(
2189 uint32_t *error_mask0, uint32_t *error_mask1)
2191 *error_mask0 = 0x00000000;
2192 *error_mask1 = 0x00FFFEFF;
2195 static void msm_vfe40_get_overflow_mask(uint32_t *overflow_mask)
2197 *overflow_mask = 0x00FFFE7E;
2200 static void msm_vfe40_get_rdi_wm_mask(struct vfe_device *vfe_dev,
2201 uint32_t *rdi_wm_mask)
2203 *rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask;
2206 static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev,
2207 uint32_t *irq0_mask, uint32_t *irq1_mask)
2209 *irq0_mask = vfe_dev->irq0_mask;
2210 *irq1_mask = vfe_dev->irq1_mask;
2213 static void msm_vfe40_get_halt_restart_mask(uint32_t *irq0_mask,
2214 uint32_t *irq1_mask)
2216 *irq0_mask = BIT(31);
2217 *irq1_mask = BIT(8);
2220 static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = {
2224 .num_rdi_master = 3,
2226 .scratch_buf_range = SZ_32M + SZ_4M,
2229 static struct msm_vfe_stats_hardware_info msm_vfe40_stats_hw_info = {
2230 .stats_capability_mask =
2231 1 << MSM_ISP_STATS_BE | 1 << MSM_ISP_STATS_BF |
2232 1 << MSM_ISP_STATS_BG | 1 << MSM_ISP_STATS_BHIST |
2233 1 << MSM_ISP_STATS_AWB | 1 << MSM_ISP_STATS_IHIST |
2234 1 << MSM_ISP_STATS_RS | 1 << MSM_ISP_STATS_CS,
2235 .stats_ping_pong_offset = stats_pingpong_offset_map,
2236 .num_stats_type = VFE40_NUM_STATS_TYPE,
2237 .num_stats_comp_mask = 2,
2240 struct msm_vfe_hardware_info vfe40_hw_info = {
2242 .num_iommu_secure_ctx = 1,
2243 .vfe_clk_idx = VFE40_CLK_IDX,
2244 .runtime_axi_update = 0,
2249 .read_and_clear_irq_status =
2250 msm_vfe40_read_and_clear_irq_status,
2251 .read_irq_status = msm_vfe40_read_irq_status,
2252 .process_camif_irq = msm_vfe40_process_input_irq,
2253 .process_reset_irq = msm_vfe40_process_reset_irq,
2254 .process_halt_irq = msm_vfe40_process_halt_irq,
2255 .process_reset_irq = msm_vfe40_process_reset_irq,
2256 .process_reg_update = msm_vfe40_process_reg_update,
2257 .process_axi_irq = msm_isp_process_axi_irq,
2258 .process_stats_irq = msm_isp_process_stats_irq,
2259 .process_epoch_irq = msm_vfe40_process_epoch_irq,
2260 .config_irq = msm_vfe40_config_irq,
2261 .preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
2264 .reload_wm = msm_vfe40_axi_reload_wm,
2265 .enable_wm = msm_vfe40_axi_enable_wm,
2266 .cfg_io_format = msm_vfe40_cfg_io_format,
2267 .cfg_comp_mask = msm_vfe40_axi_cfg_comp_mask,
2268 .clear_comp_mask = msm_vfe40_axi_clear_comp_mask,
2269 .cfg_wm_irq_mask = msm_vfe40_axi_cfg_wm_irq_mask,
2270 .clear_wm_irq_mask = msm_vfe40_axi_clear_wm_irq_mask,
2271 .cfg_framedrop = msm_vfe40_cfg_framedrop,
2272 .clear_framedrop = msm_vfe40_clear_framedrop,
2273 .cfg_wm_reg = msm_vfe40_axi_cfg_wm_reg,
2274 .clear_wm_reg = msm_vfe40_axi_clear_wm_reg,
2275 .cfg_wm_xbar_reg = msm_vfe40_axi_cfg_wm_xbar_reg,
2276 .clear_wm_xbar_reg = msm_vfe40_axi_clear_wm_xbar_reg,
2277 .cfg_ub = msm_vfe47_cfg_axi_ub,
2278 .read_wm_ping_pong_addr =
2279 msm_vfe40_read_wm_ping_pong_addr,
2280 .update_ping_pong_addr =
2281 msm_vfe40_update_ping_pong_addr,
2282 .get_comp_mask = msm_vfe40_get_comp_mask,
2283 .get_wm_mask = msm_vfe40_get_wm_mask,
2284 .get_pingpong_status = msm_vfe40_get_pingpong_status,
2285 .halt = msm_vfe40_axi_halt,
2286 .restart = msm_vfe40_axi_restart,
2287 .update_cgc_override =
2288 msm_vfe40_axi_update_cgc_override,
2289 .ub_reg_offset = msm_vfe40_ub_reg_offset,
2290 .get_ub_size = msm_vfe40_get_ub_size,
2293 .reg_update = msm_vfe40_reg_update,
2294 .cfg_input_mux = msm_vfe40_cfg_input_mux,
2295 .update_camif_state = msm_vfe40_update_camif_state,
2296 .start_fetch_eng = msm_vfe40_start_fetch_engine,
2297 .cfg_rdi_reg = msm_vfe40_cfg_rdi_reg,
2298 .reset_hw = msm_vfe40_reset_hardware,
2299 .init_hw = msm_vfe47_init_hardware,
2300 .init_hw_reg = msm_vfe40_init_hardware_reg,
2301 .clear_status_reg = msm_vfe40_clear_status_reg,
2302 .release_hw = msm_vfe47_release_hardware,
2303 .get_error_mask = msm_vfe40_get_error_mask,
2304 .get_overflow_mask = msm_vfe40_get_overflow_mask,
2305 .get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask,
2306 .get_irq_mask = msm_vfe40_get_irq_mask,
2307 .get_halt_restart_mask =
2308 msm_vfe40_get_halt_restart_mask,
2309 .process_error_status = msm_vfe40_process_error_status,
2310 .is_module_cfg_lock_needed =
2311 msm_vfe40_is_module_cfg_lock_needed,
2312 .ahb_clk_cfg = NULL,
2313 .start_fetch_eng_multi_pass =
2314 msm_vfe40_start_fetch_engine_multi_pass,
2315 .set_halt_restart_mask =
2316 msm_vfe40_set_halt_restart_mask,
2317 .set_bus_err_ign_mask = NULL,
2318 .get_bus_err_mask = NULL,
2321 .get_stats_idx = msm_vfe40_get_stats_idx,
2322 .check_streams = msm_vfe40_stats_check_streams,
2323 .cfg_comp_mask = msm_vfe40_stats_cfg_comp_mask,
2324 .cfg_wm_irq_mask = msm_vfe40_stats_cfg_wm_irq_mask,
2325 .clear_wm_irq_mask = msm_vfe40_stats_clear_wm_irq_mask,
2326 .cfg_wm_reg = msm_vfe40_stats_cfg_wm_reg,
2327 .clear_wm_reg = msm_vfe40_stats_clear_wm_reg,
2328 .cfg_ub = msm_vfe40_stats_cfg_ub,
2329 .enable_module = msm_vfe40_stats_enable_module,
2330 .update_ping_pong_addr =
2331 msm_vfe40_stats_update_ping_pong_addr,
2332 .get_comp_mask = msm_vfe40_stats_get_comp_mask,
2333 .get_wm_mask = msm_vfe40_stats_get_wm_mask,
2334 .get_frame_id = msm_vfe40_stats_get_frame_id,
2335 .get_pingpong_status = msm_vfe40_get_pingpong_status,
2336 .update_cgc_override =
2337 msm_vfe40_stats_update_cgc_override,
2338 .enable_stats_wm = NULL,
2341 .get_platform_data = msm_vfe47_get_platform_data,
2342 .enable_regulators = msm_vfe47_enable_regulators,
2343 .get_regulators = msm_vfe47_get_regulators,
2344 .put_regulators = msm_vfe47_put_regulators,
2345 .enable_clks = msm_vfe47_enable_clks,
2346 .get_clks = msm_vfe47_get_clks,
2347 .put_clks = msm_vfe47_put_clks,
2348 .get_clk_rates = msm_vfe47_get_clk_rates,
2349 .get_max_clk_rate = msm_vfe47_get_max_clk_rate,
2350 .set_clk_rate = msm_vfe47_set_clk_rate,
2351 .init_bw_mgr = msm_vfe47_init_bandwidth_mgr,
2352 .deinit_bw_mgr = msm_vfe47_deinit_bandwidth_mgr,
2353 .update_bw = msm_vfe47_update_bandwidth,
2356 .dmi_reg_offset = 0x918,
2357 .axi_hw_info = &msm_vfe40_axi_hw_info,
2358 .stats_hw_info = &msm_vfe40_stats_hw_info,
2359 .regulator_names = {"vdd"},
2361 EXPORT_SYMBOL(vfe40_hw_info);
2363 static const struct of_device_id msm_vfe40_dt_match[] = {
2365 .compatible = "qcom,vfe40",
2366 .data = &vfe40_hw_info,
2371 MODULE_DEVICE_TABLE(of, msm_vfe40_dt_match);
2373 static struct platform_driver vfe40_driver = {
2374 .probe = vfe_hw_probe,
2376 .name = "msm_vfe40",
2377 .owner = THIS_MODULE,
2378 .of_match_table = msm_vfe40_dt_match,
2382 static int __init msm_vfe40_init_module(void)
2384 return platform_driver_register(&vfe40_driver);
2387 static void __exit msm_vfe40_exit_module(void)
2389 platform_driver_unregister(&vfe40_driver);
2392 module_init(msm_vfe40_init_module);
2393 module_exit(msm_vfe40_exit_module);
2394 MODULE_DESCRIPTION("MSM VFE40 driver");
2395 MODULE_LICENSE("GPL v2");