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__);
182 if (qos_parms->settings) {
183 rc = of_property_read_u32_array(of_node,
185 qos_settings, qos_entries);
187 pr_err("%s: NO QOS settings\n",
192 for (i = 0; i < qos_entries; i++)
193 msm_camera_io_w(qos_settings[i],
194 vfebase + qos_regs[i]);
204 rc = of_property_read_u32(of_node, ds_parms->entries,
206 if (rc < 0 || !ds_entries) {
207 pr_err("%s: NO D/S entries found\n", __func__);
209 ds_settings = kzalloc(sizeof(uint32_t) * ds_entries,
212 pr_err("%s:%d No memory\n", __func__, __LINE__);
215 ds_regs = kzalloc(sizeof(uint32_t) * ds_entries,
218 pr_err("%s:%d No memory\n", __func__, __LINE__);
222 rc = of_property_read_u32_array(of_node, ds_parms->regs,
223 ds_regs, ds_entries);
225 pr_err("%s: NO D/S register info\n", __func__);
229 if (ds_parms->settings) {
230 rc = of_property_read_u32_array(of_node,
231 ds_parms->settings, ds_settings,
234 pr_err("%s: NO D/S settings\n",
239 for (i = 0; i < ds_entries; i++)
240 msm_camera_io_w(ds_settings[i],
241 vfebase + ds_regs[i]);
254 static int32_t msm_vfe40_init_vbif_parms(struct vfe_device *vfe_dev,
255 struct msm_vfe_hw_init_parms *vbif_parms)
257 void __iomem *vfe_vbif_base = vfe_dev->vfe_vbif_base;
258 struct device_node *of_node;
259 int32_t i = 0 , rc = 0;
260 uint32_t *vbif_settings = NULL, *vbif_regs = NULL, vbif_entries = 0;
261 of_node = vfe_dev->pdev->dev.of_node;
263 rc = of_property_read_u32(of_node, vbif_parms->entries,
265 if (rc < 0 || !vbif_entries) {
266 pr_err("%s: NO VBIF entries found\n", __func__);
268 vbif_settings = kzalloc(sizeof(uint32_t) * vbif_entries,
270 if (!vbif_settings) {
271 pr_err("%s:%d No memory\n", __func__, __LINE__);
274 vbif_regs = kzalloc(sizeof(uint32_t) * vbif_entries,
277 pr_err("%s:%d No memory\n", __func__, __LINE__);
278 kfree(vbif_settings);
281 rc = of_property_read_u32_array(of_node, vbif_parms->regs,
282 vbif_regs, vbif_entries);
284 pr_err("%s: NO VBIF info\n", __func__);
285 kfree(vbif_settings);
288 rc = of_property_read_u32_array(of_node,
289 vbif_parms->settings,
290 vbif_settings, vbif_entries);
292 pr_err("%s: NO VBIF settings\n",
294 kfree(vbif_settings);
297 for (i = 0; i < vbif_entries; i++)
300 vfe_vbif_base + vbif_regs[i]);
301 kfree(vbif_settings);
309 static void msm_vfe40_init_hardware_reg(struct vfe_device *vfe_dev)
311 struct msm_vfe_hw_init_parms qos_parms;
312 struct msm_vfe_hw_init_parms vbif_parms;
313 struct msm_vfe_hw_init_parms ds_parms;
315 qos_parms.entries = "qos-entries";
316 qos_parms.regs = "qos-regs";
317 qos_parms.settings = "qos-settings";
318 vbif_parms.entries = "vbif-entries";
319 vbif_parms.regs = "vbif-regs";
320 vbif_parms.settings = "vbif-settings";
321 ds_parms.entries = "ds-entries";
322 ds_parms.regs = "ds-regs";
323 ds_parms.settings = "ds-settings";
325 switch (vfe_dev->vfe_hw_version) {
326 case VFE40_8974V1_VERSION:
327 case VFE40_8x26_VERSION:
328 case VFE40_8916_VERSION:
329 case VFE40_8939_VERSION:
331 case VFE40_8x26V2_VERSION:
332 qos_parms.settings = "qos-v2-settings";
334 case VFE40_8974V2_VERSION:
335 case VFE40_8974V3_VERSION:
336 if (vfe_dev->vfe_hw_version == VFE40_8974V2_VERSION)
337 qos_parms.settings = "qos-v2-settings";
339 qos_parms.settings = "qos-v3-settings";
340 vbif_parms.entries = "vbif-v2-entries";
341 vbif_parms.regs = "vbif-v2-regs";
342 vbif_parms.settings = "vbif-v2-settings";
344 case VFE40_8937_VERSION:
345 case VFE40_8953_VERSION:
346 case VFE40_8917_VERSION:
348 ISP_DBG("%s: No special QOS\n", __func__);
351 msm_vfe40_init_qos_parms(vfe_dev, &qos_parms, &ds_parms);
352 msm_vfe40_init_vbif_parms(vfe_dev, &vbif_parms);
354 msm_camera_io_w(0x10000001, vfe_dev->vfe_base + 0x50);
355 msm_vfe40_config_irq(vfe_dev, 0x800000E0, 0xFEFFFF7E,
359 static void msm_vfe40_clear_status_reg(struct vfe_device *vfe_dev)
361 vfe_dev->irq0_mask = (1 << 31);
362 vfe_dev->irq1_mask = 0;
363 msm_vfe40_config_irq(vfe_dev, (1 << 31), 0,
365 msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x30);
366 msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34);
367 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
370 static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
371 uint32_t irq_status0, uint32_t irq_status1)
373 if (irq_status0 & (1 << 31))
374 complete(&vfe_dev->reset_complete);
377 static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
378 uint32_t irq_status0, uint32_t irq_status1)
380 if (irq_status1 & (1 << 8)) {
381 complete(&vfe_dev->halt_complete);
382 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
386 static void msm_vfe40_process_input_irq(struct vfe_device *vfe_dev,
387 uint32_t irq_status0, uint32_t irq_status1,
388 struct msm_isp_timestamp *ts)
390 if (!(irq_status0 & 0x1000003))
393 if (irq_status0 & (1 << 0)) {
394 ISP_DBG("%s: SOF IRQ\n", __func__);
395 msm_isp_increment_frame_id(vfe_dev, VFE_PIX_0, ts);
398 if (irq_status0 & (1 << 24)) {
399 ISP_DBG("%s: Fetch Engine Read IRQ\n", __func__);
400 msm_isp_fetch_engine_done_notify(vfe_dev,
401 &vfe_dev->fetch_engine_info);
404 if (irq_status0 & (1 << 1))
405 ISP_DBG("%s: EOF IRQ\n", __func__);
408 static void msm_vfe40_process_violation_status(
409 struct vfe_device *vfe_dev)
411 uint32_t violation_status = vfe_dev->error_info.violation_status;
412 if (!violation_status)
415 if (violation_status & (1 << 0))
416 pr_err("%s: vfe %d camif violation\n", __func__,
418 if (violation_status & (1 << 1))
419 pr_err("%s: vfe %d black violation\n", __func__,
421 if (violation_status & (1 << 2))
422 pr_err("%s: vfe %d rolloff violation\n", __func__,
424 if (violation_status & (1 << 3))
425 pr_err("%s: demux violation\n", __func__);
426 if (violation_status & (1 << 4))
427 pr_err("%s: demosaic violation\n", __func__);
428 if (violation_status & (1 << 5))
429 pr_err("%s: wb violation\n", __func__);
430 if (violation_status & (1 << 6))
431 pr_err("%s: clf violation\n", __func__);
432 if (violation_status & (1 << 7))
433 pr_err("%s: color correct violation\n", __func__);
434 if (violation_status & (1 << 8))
435 pr_err("%s: rgb lut violation\n", __func__);
436 if (violation_status & (1 << 9))
437 pr_err("%s: la violation\n", __func__);
438 if (violation_status & (1 << 10))
439 pr_err("%s: chroma enhance violation\n", __func__);
440 if (violation_status & (1 << 11))
441 pr_err("%s: chroma supress mce violation\n", __func__);
442 if (violation_status & (1 << 12))
443 pr_err("%s: skin enhance violation\n", __func__);
444 if (violation_status & (1 << 13))
445 pr_err("%s: color tranform enc violation\n", __func__);
446 if (violation_status & (1 << 14))
447 pr_err("%s: color tranform view violation\n", __func__);
448 if (violation_status & (1 << 15))
449 pr_err("%s: scale enc y violation\n", __func__);
450 if (violation_status & (1 << 16))
451 pr_err("%s: scale enc cbcr violation\n", __func__);
452 if (violation_status & (1 << 17))
453 pr_err("%s: scale view y violation\n", __func__);
454 if (violation_status & (1 << 18))
455 pr_err("%s: scale view cbcr violation\n", __func__);
456 if (violation_status & (1 << 19))
457 pr_err("%s: asf enc violation\n", __func__);
458 if (violation_status & (1 << 20))
459 pr_err("%s: asf view violation\n", __func__);
460 if (violation_status & (1 << 21))
461 pr_err("%s: crop enc y violation\n", __func__);
462 if (violation_status & (1 << 22))
463 pr_err("%s: crop enc cbcr violation\n", __func__);
464 if (violation_status & (1 << 23))
465 pr_err("%s: crop view y violation\n", __func__);
466 if (violation_status & (1 << 24))
467 pr_err("%s: crop view cbcr violation\n", __func__);
468 if (violation_status & (1 << 25))
469 pr_err("%s: realign buf y violation\n", __func__);
470 if (violation_status & (1 << 26))
471 pr_err("%s: realign buf cb violation\n", __func__);
472 if (violation_status & (1 << 27))
473 pr_err("%s: realign buf cr violation\n", __func__);
476 static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev)
478 uint32_t error_status1 = vfe_dev->error_info.error_mask1;
479 if (error_status1 & (1 << 0)) {
480 pr_err_ratelimited("%s: vfe %d camif error status: 0x%x\n",
481 __func__, vfe_dev->pdev->id,
482 vfe_dev->error_info.camif_status);
483 msm_camera_io_dump(vfe_dev->vfe_base + 0x2F4, 0x30, 1);
485 if (error_status1 & (1 << 1))
486 pr_err_ratelimited("%s: stats bhist overwrite\n", __func__);
487 if (error_status1 & (1 << 2))
488 pr_err_ratelimited("%s: stats cs overwrite\n", __func__);
489 if (error_status1 & (1 << 3))
490 pr_err_ratelimited("%s: stats ihist overwrite\n", __func__);
491 if (error_status1 & (1 << 4))
492 pr_err_ratelimited("%s: realign buf y overflow\n", __func__);
493 if (error_status1 & (1 << 5))
494 pr_err_ratelimited("%s: realign buf cb overflow\n", __func__);
495 if (error_status1 & (1 << 6))
496 pr_err_ratelimited("%s: realign buf cr overflow\n", __func__);
497 if (error_status1 & (1 << 7)) {
498 msm_vfe40_process_violation_status(vfe_dev);
500 if (error_status1 & (1 << 9)) {
501 vfe_dev->stats->imagemaster0_overflow++;
502 pr_err_ratelimited("%s: image master 0 bus overflow\n",
505 if (error_status1 & (1 << 10)) {
506 vfe_dev->stats->imagemaster1_overflow++;
507 pr_err_ratelimited("%s: image master 1 bus overflow\n",
510 if (error_status1 & (1 << 11)) {
511 vfe_dev->stats->imagemaster2_overflow++;
512 pr_err_ratelimited("%s: image master 2 bus overflow\n",
515 if (error_status1 & (1 << 12)) {
516 vfe_dev->stats->imagemaster3_overflow++;
517 pr_err_ratelimited("%s: image master 3 bus overflow\n",
520 if (error_status1 & (1 << 13)) {
521 vfe_dev->stats->imagemaster4_overflow++;
522 pr_err_ratelimited("%s: image master 4 bus overflow\n",
525 if (error_status1 & (1 << 14)) {
526 vfe_dev->stats->imagemaster5_overflow++;
527 pr_err_ratelimited("%s: image master 5 bus overflow\n",
530 if (error_status1 & (1 << 15)) {
531 vfe_dev->stats->imagemaster6_overflow++;
532 pr_err_ratelimited("%s: image master 6 bus overflow\n",
535 if (error_status1 & (1 << 16)) {
536 vfe_dev->stats->be_overflow++;
537 pr_err_ratelimited("%s: status be bus overflow\n", __func__);
539 if (error_status1 & (1 << 17)) {
540 vfe_dev->stats->bg_overflow++;
541 pr_err_ratelimited("%s: status bg bus overflow\n", __func__);
543 if (error_status1 & (1 << 18)) {
544 vfe_dev->stats->bf_overflow++;
545 pr_err_ratelimited("%s: status bf bus overflow\n", __func__);
547 if (error_status1 & (1 << 19)) {
548 vfe_dev->stats->awb_overflow++;
549 pr_err_ratelimited("%s: status awb bus overflow\n", __func__);
551 if (error_status1 & (1 << 20)) {
552 vfe_dev->stats->rs_overflow++;
553 pr_err_ratelimited("%s: status rs bus overflow\n", __func__);
555 if (error_status1 & (1 << 21)) {
556 vfe_dev->stats->cs_overflow++;
557 pr_err_ratelimited("%s: status cs bus overflow\n", __func__);
559 if (error_status1 & (1 << 22)) {
560 vfe_dev->stats->ihist_overflow++;
561 pr_err_ratelimited("%s: status ihist bus overflow\n", __func__);
563 if (error_status1 & (1 << 23)) {
564 vfe_dev->stats->skinbhist_overflow++;
565 pr_err_ratelimited("%s: status skin bhist bus overflow\n",
569 /* Update ab/ib values for any overflow that may have occured*/
570 if ((error_status1 >> 9) & 0x7FFF)
571 msm_isp_update_last_overflow_ab_ib(vfe_dev);
574 static void msm_vfe40_read_and_clear_irq_status(struct vfe_device *vfe_dev,
575 uint32_t *irq_status0, uint32_t *irq_status1)
577 *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
578 *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
580 * Ignore composite 2/3 irq which is used for dual VFE only
582 if (*irq_status0 & 0x6000000)
583 *irq_status0 &= ~(0x18000000);
584 msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
585 msm_camera_io_w(*irq_status1, vfe_dev->vfe_base + 0x34);
586 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
587 if (*irq_status0 & 0x18000000) {
588 pr_err_ratelimited("%s: Protection triggered\n", __func__);
589 *irq_status0 &= ~(0x18000000);
592 *irq_status0 &= vfe_dev->irq0_mask;
593 *irq_status1 &= vfe_dev->irq1_mask;
595 (*irq_status0 == msm_camera_io_r(vfe_dev->vfe_base + 0x38))) {
596 msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x30);
597 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
600 if (*irq_status1 & (1 << 0)) {
601 vfe_dev->error_info.camif_status =
602 msm_camera_io_r(vfe_dev->vfe_base + 0x31C);
603 msm_vfe40_config_irq(vfe_dev, 0, (1 << 0), MSM_ISP_IRQ_DISABLE);
606 if (*irq_status1 & (1 << 7))
607 vfe_dev->error_info.violation_status |=
608 msm_camera_io_r(vfe_dev->vfe_base + 0x48);
612 static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev,
613 uint32_t *irq_status0, uint32_t *irq_status1)
615 *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38);
616 *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C);
619 static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
620 uint32_t irq_status0, uint32_t irq_status1,
621 struct msm_isp_timestamp *ts)
623 enum msm_vfe_input_src i;
625 uint8_t reg_updated = 0;
628 if (!(irq_status0 & 0xF0))
630 /* Shift status bits so that PIX REG UPDATE is 1st bit */
631 shift_irq = ((irq_status0 & 0xF0) >> 4);
632 for (i = VFE_PIX_0; i <= VFE_RAW_2; i++) {
633 if (shift_irq & BIT(i)) {
634 reg_updated |= BIT(i);
635 ISP_DBG("%s REG_UPDATE IRQ %x\n", __func__,
639 msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE,
641 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
642 MSM_ISP_COMP_IRQ_REG_UPD, ts);
643 msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
644 MSM_ISP_COMP_IRQ_REG_UPD);
645 if (vfe_dev->axi_data.src_info[i].stream_count
647 vfe_dev->axi_data.src_info[i].
648 raw_stream_count == 0 &&
649 vfe_dev->axi_data.src_info[i].active)
650 vfe_dev->hw_info->vfe_ops.core_ops.
651 reg_update(vfe_dev, i);
656 msm_isp_increment_frame_id(vfe_dev, i, ts);
657 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts);
658 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
659 MSM_ISP_COMP_IRQ_REG_UPD, ts);
661 * Reg Update is pseudo SOF for RDI,
662 * so request every frame
664 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
666 /* reg upd is also epoch for RDI */
667 msm_isp_process_reg_upd_epoch_irq(vfe_dev, i,
668 MSM_ISP_COMP_IRQ_EPOCH, ts);
671 pr_err("%s: Error case\n", __func__);
677 spin_lock_irqsave(&vfe_dev->reg_update_lock, flags);
678 if (reg_updated & BIT(VFE_PIX_0))
679 vfe_dev->reg_updated = 1;
681 vfe_dev->reg_update_requested &= ~reg_updated;
682 spin_unlock_irqrestore(&vfe_dev->reg_update_lock, flags);
685 static void msm_vfe40_reg_update(struct vfe_device *vfe_dev,
686 enum msm_vfe_input_src frame_src)
688 uint32_t update_mask = 0;
691 /* This HW supports upto VFE_RAW_2 */
692 if (frame_src > VFE_RAW_2 && frame_src != VFE_SRC_MAX) {
693 pr_err("%s Error case\n", __func__);
698 * If frame_src == VFE_SRC_MAX request reg_update on all
701 if (frame_src == VFE_SRC_MAX)
704 update_mask = BIT((uint32_t)frame_src);
705 ISP_DBG("%s update_mask %x\n", __func__, update_mask);
707 spin_lock_irqsave(&vfe_dev->reg_update_lock, flags);
708 vfe_dev->axi_data.src_info[VFE_PIX_0].reg_update_frame_id =
709 vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
710 vfe_dev->reg_update_requested |= update_mask;
711 vfe_dev->common_data->dual_vfe_res->reg_update_mask[vfe_dev->pdev->id] =
712 vfe_dev->reg_update_requested;
713 if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) &&
714 ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) {
715 if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) {
716 pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__);
717 spin_unlock_irqrestore(&vfe_dev->reg_update_lock,
721 msm_camera_io_w_mb(update_mask,
722 vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]
724 msm_camera_io_w_mb(update_mask,
725 vfe_dev->vfe_base + 0x378);
726 } else if (!vfe_dev->is_split ||
727 ((frame_src == VFE_PIX_0) &&
728 (vfe_dev->axi_data.src_info[VFE_PIX_0].stream_count == 0) &&
729 (vfe_dev->axi_data.src_info[VFE_PIX_0].
730 raw_stream_count == 0)) ||
731 (frame_src >= VFE_RAW_0 && frame_src <= VFE_SRC_MAX)) {
732 msm_camera_io_w_mb(update_mask,
733 vfe_dev->vfe_base + 0x378);
735 spin_unlock_irqrestore(&vfe_dev->reg_update_lock, flags);
738 static void msm_vfe40_process_epoch_irq(struct vfe_device *vfe_dev,
739 uint32_t irq_status0, uint32_t irq_status1,
740 struct msm_isp_timestamp *ts)
742 if (!(irq_status0 & 0xc))
745 if (irq_status0 & BIT(2)) {
746 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
747 ISP_DBG("%s: EPOCH0 IRQ\n", __func__);
748 msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
749 MSM_ISP_COMP_IRQ_EPOCH, ts);
750 msm_isp_process_stats_reg_upd_epoch_irq(vfe_dev,
751 MSM_ISP_COMP_IRQ_EPOCH);
752 msm_isp_update_error_frame_count(vfe_dev);
753 if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
754 && vfe_dev->axi_data.src_info[VFE_PIX_0].
756 ISP_DBG("%s: SOF IRQ\n", __func__);
757 msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts);
758 msm_isp_process_reg_upd_epoch_irq(vfe_dev, VFE_PIX_0,
759 MSM_ISP_COMP_IRQ_REG_UPD, ts);
760 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(
766 static long msm_vfe40_reset_hardware(struct vfe_device *vfe_dev,
767 uint32_t first_start, uint32_t blocking_call)
770 init_completion(&vfe_dev->reset_complete);
773 msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
775 msm_camera_io_w_mb(0x1EF, vfe_dev->vfe_base + 0xC);
776 msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30);
777 msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34);
778 msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24);
779 vfe_dev->hw_info->vfe_ops.axi_ops.
780 reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0003FFFF);
785 rc = wait_for_completion_timeout(
786 &vfe_dev->reset_complete, msecs_to_jiffies(50));
791 static void msm_vfe40_axi_reload_wm(struct vfe_device *vfe_dev,
792 void __iomem *vfe_base, uint32_t reload_mask)
794 msm_camera_io_w_mb(reload_mask, vfe_base + 0x4C);
797 static void msm_vfe40_axi_update_cgc_override(struct vfe_device *vfe_dev,
798 uint8_t wm_idx, uint8_t enable)
802 /* Change CGC override */
803 val = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
805 val |= (1 << wm_idx);
807 val &= ~(1 << wm_idx);
808 msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x974);
811 static void msm_vfe40_axi_enable_wm(void __iomem *vfe_base,
812 uint8_t wm_idx, uint8_t enable)
815 val = msm_camera_io_r(vfe_base + VFE40_WM_BASE(wm_idx));
820 msm_camera_io_w_mb(val,
821 vfe_base + VFE40_WM_BASE(wm_idx));
824 static void msm_vfe40_axi_cfg_comp_mask(struct vfe_device *vfe_dev,
825 struct msm_vfe_axi_stream *stream_info)
827 struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
828 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
829 uint32_t comp_mask, comp_mask_index;
831 comp_mask_index = stream_info->comp_mask_index[vfe_idx];
833 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
834 comp_mask &= ~(0x7F << (comp_mask_index * 8));
835 comp_mask |= (axi_data->composite_info[comp_mask_index].
836 stream_composite_mask << (comp_mask_index * 8));
838 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
839 msm_vfe40_config_irq(vfe_dev, 1 << (comp_mask_index + 25), 0,
843 static void msm_vfe40_axi_clear_comp_mask(struct vfe_device *vfe_dev,
844 struct msm_vfe_axi_stream *stream_info)
846 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
847 uint32_t comp_mask, comp_mask_index;
849 comp_mask_index = stream_info->comp_mask_index[vfe_idx];
850 vfe_dev->irq0_mask &= ~BIT(27);
852 comp_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x40);
853 comp_mask &= ~(0x7F << (comp_mask_index * 8));
855 msm_camera_io_w(comp_mask, vfe_dev->vfe_base + 0x40);
856 msm_vfe40_config_irq(vfe_dev, (1 << (comp_mask_index + 25)), 0,
857 MSM_ISP_IRQ_DISABLE);
860 static void msm_vfe40_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev,
861 struct msm_vfe_axi_stream *stream_info)
863 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
865 msm_vfe40_config_irq(vfe_dev, 1 << (stream_info->wm[vfe_idx][0] + 8), 0,
869 static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev,
870 struct msm_vfe_axi_stream *stream_info)
872 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
874 vfe_dev->irq0_mask &= ~(1 << (stream_info->wm[vfe_idx][0] + 8));
875 msm_vfe40_config_irq(vfe_dev, (1 << (stream_info->wm[vfe_idx][0] + 8)),
876 0, MSM_ISP_IRQ_DISABLE);
879 static void msm_vfe40_cfg_framedrop(struct vfe_device *vfe_dev,
880 struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern,
881 uint32_t framedrop_period)
883 void __iomem *vfe_base = vfe_dev->vfe_base;
885 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
887 for (i = 0; i < stream_info->num_planes; i++) {
888 msm_camera_io_w(framedrop_pattern, vfe_base +
889 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
890 temp = msm_camera_io_r(vfe_base +
891 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
893 msm_camera_io_w(temp | (framedrop_period - 1) << 2,
894 vfe_base + VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0xC);
897 msm_camera_io_w_mb(0x1, vfe_base + 0x378);
900 static void msm_vfe40_clear_framedrop(struct vfe_device *vfe_dev,
901 struct msm_vfe_axi_stream *stream_info)
904 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
906 for (i = 0; i < stream_info->num_planes; i++)
907 msm_camera_io_w(0, vfe_dev->vfe_base +
908 VFE40_WM_BASE(stream_info->wm[vfe_idx][i]) + 0x1C);
911 static int32_t msm_vfe40_convert_bpp_to_reg(int32_t bpp, uint32_t *bpp_reg)
926 pr_err("%s:%d invalid bpp %d", __func__, __LINE__, bpp);
932 static int32_t msm_vfe40_convert_io_fmt_to_reg(
933 enum msm_isp_pack_fmt pack_format, uint32_t *pack_reg)
937 switch (pack_format) {
957 pr_err("%s: invalid pack fmt %d!\n", __func__, pack_format);
963 static int32_t msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
964 enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
967 int bpp = 0, read_bpp = 0;
968 enum msm_isp_pack_fmt pack_fmt = 0, read_pack_fmt = 0;
969 uint32_t bpp_reg = 0, pack_reg = 0;
970 uint32_t read_bpp_reg = 0, read_pack_reg = 0;
971 uint32_t io_format_reg = 0; /*io format register bit*/
973 io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
974 if ((stream_src < RDI_INTF_0) &&
975 (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux ==
977 read_bpp = msm_isp_get_bit_per_pixel(
978 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
979 rc = msm_vfe40_convert_bpp_to_reg(read_bpp, &read_bpp_reg);
981 pr_err("%s: convert_bpp_to_reg err! in_bpp %d rc %d\n",
982 __func__, read_bpp, rc);
985 read_pack_fmt = msm_isp_get_pack_format(
986 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
987 rc = msm_vfe40_convert_io_fmt_to_reg(
988 read_pack_fmt, &read_pack_reg);
990 pr_err("%s: convert_io_fmt_to_reg err! rc = %d\n",
994 /*use input format(v4l2_pix_fmt) to get pack format*/
995 io_format_reg &= 0xFFC8FFFF;
996 io_format_reg |= (read_bpp_reg << 20 | read_pack_reg << 16);
999 bpp = msm_isp_get_bit_per_pixel(io_format);
1000 rc = msm_vfe40_convert_bpp_to_reg(bpp, &bpp_reg);
1002 pr_err("%s: convert_bpp_to_reg err! bpp %d rc = %d\n",
1007 switch (stream_src) {
1009 case PIX_VIEWFINDER:
1011 io_format_reg &= 0xFFFFCFFF;
1012 io_format_reg |= bpp_reg << 12;
1015 /*use output format(v4l2_pix_fmt) to get pack format*/
1016 pack_fmt = msm_isp_get_pack_format(io_format);
1017 rc = msm_vfe40_convert_io_fmt_to_reg(pack_fmt, &pack_reg);
1019 pr_err("%s: convert_io_fmt_to_reg err! rc = %d\n",
1023 io_format_reg &= 0xFFFFFFC8;
1024 io_format_reg |= bpp_reg << 4 | pack_reg;
1030 pr_err("%s: Invalid stream source\n", __func__);
1033 msm_camera_io_w(io_format_reg, vfe_dev->vfe_base + 0x54);
1037 static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev,
1041 uint32_t bufq_handle = 0;
1042 struct msm_isp_buffer *buf = NULL;
1043 struct msm_vfe_fetch_eng_start *fe_cfg = arg;
1044 struct msm_isp_buffer_mapped_info mapped_info;
1046 if (vfe_dev->fetch_engine_info.is_busy == 1) {
1047 pr_err("%s: fetch engine busy\n", __func__);
1050 memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
1051 /* There is other option of passing buffer address from user,
1052 in such case, driver needs to map the buffer and use it*/
1053 vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
1054 vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
1055 vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
1056 vfe_dev->fetch_engine_info.fd = fe_cfg->fd;
1058 if (!fe_cfg->offline_mode) {
1059 bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
1060 vfe_dev->buf_mgr, fe_cfg->session_id,
1062 vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
1064 mutex_lock(&vfe_dev->buf_mgr->lock);
1065 rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
1066 vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
1067 if (rc < 0 || !buf) {
1068 pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
1070 mutex_unlock(&vfe_dev->buf_mgr->lock);
1073 mapped_info = buf->mapped_info[0];
1074 buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
1075 mutex_unlock(&vfe_dev->buf_mgr->lock);
1077 rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
1078 &mapped_info, fe_cfg->fd);
1080 pr_err("%s: can not map buffer\n", __func__);
1084 vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
1085 vfe_dev->fetch_engine_info.is_busy = 1;
1087 msm_camera_io_w(mapped_info.paddr, vfe_dev->vfe_base + 0x228);
1088 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
1090 msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
1091 msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);
1093 ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id);
1097 static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev,
1101 uint32_t bufq_handle = 0;
1102 struct msm_isp_buffer *buf = NULL;
1103 struct msm_vfe_fetch_eng_multi_pass_start *fe_cfg = arg;
1104 struct msm_isp_buffer_mapped_info mapped_info;
1106 if (vfe_dev->fetch_engine_info.is_busy == 1) {
1107 pr_err("%s: fetch engine busy\n", __func__);
1110 memset(&mapped_info, 0, sizeof(struct msm_isp_buffer_mapped_info));
1111 /* There is other option of passing buffer address from user,
1112 * in such case, driver needs to map the buffer and use it
1114 vfe_dev->fetch_engine_info.session_id = fe_cfg->session_id;
1115 vfe_dev->fetch_engine_info.stream_id = fe_cfg->stream_id;
1116 vfe_dev->fetch_engine_info.offline_mode = fe_cfg->offline_mode;
1117 vfe_dev->fetch_engine_info.fd = fe_cfg->fd;
1119 if (!fe_cfg->offline_mode) {
1120 bufq_handle = vfe_dev->buf_mgr->ops->get_bufq_handle(
1121 vfe_dev->buf_mgr, fe_cfg->session_id,
1123 vfe_dev->fetch_engine_info.bufq_handle = bufq_handle;
1125 mutex_lock(&vfe_dev->buf_mgr->lock);
1126 rc = vfe_dev->buf_mgr->ops->get_buf_by_index(
1127 vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf);
1128 if (rc < 0 || !buf) {
1129 pr_err("%s: No fetch buffer rc= %d buf= %pK\n",
1131 mutex_unlock(&vfe_dev->buf_mgr->lock);
1134 mapped_info = buf->mapped_info[0];
1135 buf->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
1136 mutex_unlock(&vfe_dev->buf_mgr->lock);
1138 rc = vfe_dev->buf_mgr->ops->map_buf(vfe_dev->buf_mgr,
1139 &mapped_info, fe_cfg->fd);
1141 pr_err("%s: can not map buffer\n", __func__);
1145 vfe_dev->fetch_engine_info.buf_idx = fe_cfg->buf_idx;
1146 vfe_dev->fetch_engine_info.is_busy = 1;
1148 msm_camera_io_w(mapped_info.paddr + fe_cfg->input_buf_offset,
1149 vfe_dev->vfe_base + 0x228);
1151 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378);
1153 msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C);
1154 msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C);
1156 ISP_DBG("%s:VFE%d Fetch Engine ready\n", __func__, vfe_dev->pdev->id);
1160 static void msm_vfe40_cfg_fetch_engine(struct vfe_device *vfe_dev,
1161 struct msm_vfe_pix_cfg *pix_cfg)
1163 uint32_t x_size_word;
1165 uint32_t main_unpack_pattern = 0;
1166 struct msm_vfe_fetch_engine_cfg *fe_cfg = NULL;
1168 if (pix_cfg->input_mux != EXTERNAL_READ) {
1169 pr_err("%s: Invalid mux configuration - mux: %d",
1170 __func__, pix_cfg->input_mux);
1174 fe_cfg = &pix_cfg->fetch_engine_cfg;
1175 pr_debug("%s: fetch_dbg wd x ht buf = %d x %d, fe = %d x %d\n",
1176 __func__, fe_cfg->buf_width, fe_cfg->buf_height,
1177 fe_cfg->fetch_width, fe_cfg->fetch_height);
1179 vfe_dev->hw_info->vfe_ops.axi_ops.update_cgc_override(vfe_dev,
1180 VFE40_BUS_RD_CGC_OVERRIDE_BIT, 1);
1182 temp = msm_camera_io_r(vfe_dev->vfe_base + 0x50);
1185 msm_camera_io_w(temp, vfe_dev->vfe_base + 0x50);
1187 msm_vfe40_config_irq(vfe_dev, (1 << 24), 0,
1188 MSM_ISP_IRQ_ENABLE);
1190 msm_camera_io_w((fe_cfg->fetch_height - 1),
1191 vfe_dev->vfe_base + 0x238);
1193 /* need to update to use formulae to calculate X_SIZE_WORD*/
1194 x_size_word = msm_isp_cal_word_per_line(
1195 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format,
1198 msm_camera_io_w((x_size_word - 1) << 16, vfe_dev->vfe_base + 0x23C);
1200 x_size_word = msm_isp_cal_word_per_line(
1201 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format,
1202 fe_cfg->fetch_width);
1204 temp = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
1205 temp |= 2 << 16 | pix_cfg->pixel_pattern;
1206 msm_camera_io_w(temp, vfe_dev->vfe_base + 0x1C);
1208 if (vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
1209 msm_camera_io_w(x_size_word << 17 |
1210 (fe_cfg->buf_height-1) << 4 |
1211 VFE40_FETCH_BURST_LEN,
1212 vfe_dev->vfe_base + 0x240);
1213 msm_camera_io_w(0 << 29 | 2 << 26 |
1214 (fe_cfg->buf_width - 1) << 13 |
1215 (fe_cfg->buf_height - 1),
1216 vfe_dev->vfe_base + 0x244);
1218 msm_camera_io_w(x_size_word << 16 |
1219 (fe_cfg->buf_height-1) << 4 |
1220 VFE40_FETCH_BURST_LEN,
1221 vfe_dev->vfe_base + 0x240);
1222 msm_camera_io_w(0 << 28 | 2 << 25 |
1223 (fe_cfg->buf_width - 1) << 12 |
1224 (fe_cfg->buf_height - 1),
1225 vfe_dev->vfe_base + 0x244);
1228 /* need to use formulae to calculate MAIN_UNPACK_PATTERN*/
1229 switch (vfe_dev->axi_data.src_info[VFE_PIX_0].input_format) {
1230 case V4L2_PIX_FMT_P16BGGR10:
1231 case V4L2_PIX_FMT_P16GBRG10:
1232 case V4L2_PIX_FMT_P16GRBG10:
1233 case V4L2_PIX_FMT_P16RGGB10:
1234 main_unpack_pattern = 0xB210;
1237 main_unpack_pattern = 0xF6543210;
1240 msm_camera_io_w(main_unpack_pattern,
1241 vfe_dev->vfe_base + 0x248);
1242 msm_camera_io_w(0xF, vfe_dev->vfe_base + 0x264);
1247 static void msm_vfe40_cfg_testgen(struct vfe_device *vfe_dev,
1248 struct msm_vfe_testgen_cfg *testgen_cfg)
1250 uint32_t bit_per_pixel = 0;
1251 uint32_t bpp_reg = 0;
1252 uint32_t bayer_pix_pattern_reg = 0;
1253 uint32_t unicolorbar_reg = 0;
1254 uint32_t unicolor_enb = 0;
1256 bit_per_pixel = msm_isp_get_bit_per_pixel(
1257 vfe_dev->axi_data.src_info[VFE_PIX_0].input_format);
1259 switch (bit_per_pixel) {
1273 pr_err("%s: invalid bpp %d\n", __func__, bit_per_pixel);
1277 msm_camera_io_w(bpp_reg << 16 | testgen_cfg->burst_num_frame,
1278 vfe_dev->vfe_base + 0x940);
1280 msm_camera_io_w(((testgen_cfg->lines_per_frame - 1) << 16) |
1281 (testgen_cfg->pixels_per_line - 1), vfe_dev->vfe_base + 0x944);
1283 msm_camera_io_w(testgen_cfg->h_blank, vfe_dev->vfe_base + 0x958);
1285 msm_camera_io_w((1 << 16) | testgen_cfg->v_blank,
1286 vfe_dev->vfe_base + 0x95C);
1288 switch (testgen_cfg->pixel_bayer_pattern) {
1289 case ISP_BAYER_RGRGRG:
1290 bayer_pix_pattern_reg = 0x0;
1292 case ISP_BAYER_GRGRGR:
1293 bayer_pix_pattern_reg = 0x1;
1295 case ISP_BAYER_BGBGBG:
1296 bayer_pix_pattern_reg = 0x10;
1298 case ISP_BAYER_GBGBGB:
1299 bayer_pix_pattern_reg = 0x11;
1302 pr_err("%s: invalid pix pattern %d\n",
1303 __func__, bit_per_pixel);
1307 if (testgen_cfg->color_bar_pattern == COLOR_BAR_8_COLOR) {
1311 switch (testgen_cfg->color_bar_pattern) {
1312 case UNICOLOR_WHITE:
1313 unicolorbar_reg = 0x0;
1315 case UNICOLOR_YELLOW:
1316 unicolorbar_reg = 0x1;
1319 unicolorbar_reg = 0x10;
1321 case UNICOLOR_GREEN:
1322 unicolorbar_reg = 0x11;
1324 case UNICOLOR_MAGENTA:
1325 unicolorbar_reg = 0x100;
1328 unicolorbar_reg = 0x101;
1331 unicolorbar_reg = 0x110;
1333 case UNICOLOR_BLACK:
1334 unicolorbar_reg = 0x111;
1337 pr_err("%s: invalid colorbar %d\n",
1338 __func__, testgen_cfg->color_bar_pattern);
1342 msm_camera_io_w((testgen_cfg->rotate_period << 8) |
1343 (bayer_pix_pattern_reg << 6) | (unicolor_enb << 4) |
1344 (unicolorbar_reg), vfe_dev->vfe_base + 0x968);
1347 static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
1348 struct msm_vfe_pix_cfg *pix_cfg)
1350 uint16_t first_pixel, last_pixel, first_line, last_line;
1351 uint16_t epoch_line1;
1352 struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
1353 uint32_t val, subsample_period, subsample_pattern;
1354 struct msm_vfe_camif_subsample_cfg *subsample_cfg =
1355 &pix_cfg->camif_cfg.subsample_cfg;
1356 uint16_t bus_sub_en = 0;
1358 vfe_dev->dual_vfe_enable = camif_cfg->is_split;
1360 msm_camera_io_w(pix_cfg->input_mux << 16 | pix_cfg->pixel_pattern,
1361 vfe_dev->vfe_base + 0x1C);
1363 first_pixel = camif_cfg->first_pixel;
1364 last_pixel = camif_cfg->last_pixel;
1365 first_line = camif_cfg->first_line;
1366 last_line = camif_cfg->last_line;
1367 epoch_line1 = camif_cfg->epoch_line1;
1369 if ((epoch_line1 <= 0) || (epoch_line1 > last_line))
1370 epoch_line1 = last_line - 50;
1372 if ((last_line - epoch_line1) > 100)
1373 epoch_line1 = last_line - 100;
1375 subsample_period = camif_cfg->subsample_cfg.irq_subsample_period;
1376 subsample_pattern = camif_cfg->subsample_cfg.irq_subsample_pattern;
1378 msm_camera_io_w(camif_cfg->lines_per_frame << 16 |
1379 camif_cfg->pixels_per_line, vfe_dev->vfe_base + 0x300);
1381 msm_camera_io_w(first_pixel << 16 | last_pixel,
1382 vfe_dev->vfe_base + 0x304);
1384 msm_camera_io_w(first_line << 16 | last_line,
1385 vfe_dev->vfe_base + 0x308);
1387 /*configure EPOCH0: 20 lines, and
1388 * configure EPOCH1: epoch_line1 before EOF
1390 msm_camera_io_w_mb(0x140000 | epoch_line1,
1391 vfe_dev->vfe_base + 0x318);
1392 pr_debug("%s:%d: epoch_line1: %d\n",
1393 __func__, __LINE__, epoch_line1);
1394 if (subsample_period && subsample_pattern) {
1395 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1397 val = (subsample_period - 1) << 16;
1398 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1399 ISP_DBG("%s:camif PERIOD %x PATTERN %x\n",
1400 __func__, subsample_period, subsample_pattern);
1402 val = subsample_pattern;
1403 msm_camera_io_w(val, vfe_dev->vfe_base + 0x314);
1405 msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x314);
1407 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2E8);
1408 val |= camif_cfg->camif_input;
1409 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2E8);
1411 if (subsample_cfg->pixel_skip || subsample_cfg->line_skip) {
1413 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1415 val = val | bus_sub_en << 5;
1416 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1417 subsample_cfg->pixel_skip &= 0x0000FFFF;
1418 subsample_cfg->line_skip &= 0x0000FFFF;
1419 msm_camera_io_w((subsample_cfg->line_skip << 16) |
1420 subsample_cfg->pixel_skip,
1421 vfe_dev->vfe_base + 0x30C);
1422 if (subsample_cfg->first_pixel ||
1423 subsample_cfg->last_pixel ||
1424 subsample_cfg->first_line ||
1425 subsample_cfg->last_line) {
1427 subsample_cfg->first_pixel << 16 |
1428 subsample_cfg->last_pixel,
1429 vfe_dev->vfe_base + 0x8A4);
1431 subsample_cfg->first_line << 16 |
1432 subsample_cfg->last_line,
1433 vfe_dev->vfe_base + 0x8A8);
1434 val = msm_camera_io_r(
1435 vfe_dev->vfe_base + 0x2F8);
1437 msm_camera_io_w(val,
1438 vfe_dev->vfe_base + 0x2F8);
1441 ISP_DBG("%s:camif raw op fmt %d\n",
1442 __func__, subsample_cfg->output_format);
1443 /* Pdaf output will be sent in PLAIN16 format*/
1444 val = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
1445 switch (subsample_cfg->output_format) {
1449 case CAMIF_PLAIN_16:
1452 case CAMIF_MIPI_RAW:
1455 case CAMIF_QCOM_RAW:
1459 msm_camera_io_w(val, vfe_dev->vfe_base + 0x54);
1463 static void msm_vfe40_cfg_input_mux(struct vfe_device *vfe_dev,
1464 struct msm_vfe_pix_cfg *pix_cfg)
1466 uint32_t core_cfg = 0;
1469 core_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x1C);
1470 core_cfg &= 0xFFFCFFFF;
1472 switch (pix_cfg->input_mux) {
1474 core_cfg |= 0x0 << 16;
1475 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1476 msm_vfe40_cfg_camif(vfe_dev, pix_cfg);
1479 /* Change CGC override */
1480 val = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
1482 msm_camera_io_w(val, vfe_dev->vfe_base + 0x974);
1484 /* CAMIF and TESTGEN will both go thorugh CAMIF*/
1485 core_cfg |= 0x1 << 16;
1486 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1487 msm_vfe40_cfg_camif(vfe_dev, pix_cfg);
1488 msm_vfe40_cfg_testgen(vfe_dev, &pix_cfg->testgen_cfg);
1491 core_cfg |= 0x2 << 16;
1492 msm_camera_io_w_mb(core_cfg, vfe_dev->vfe_base + 0x1C);
1493 msm_vfe40_cfg_fetch_engine(vfe_dev, pix_cfg);
1496 pr_err("%s: Unsupported input mux %d\n",
1497 __func__, pix_cfg->input_mux);
1503 static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
1504 enum msm_isp_camif_update_state update_state)
1507 bool bus_en, vfe_en;
1508 if (update_state == NO_UPDATE)
1511 if (update_state == ENABLE_CAMIF) {
1512 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x30);
1513 msm_camera_io_w_mb(0x81, vfe_dev->vfe_base + 0x34);
1514 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
1515 msm_vfe40_config_irq(vfe_dev, 0xFF, 0x81,
1516 MSM_ISP_IRQ_ENABLE);
1519 ((vfe_dev->axi_data.
1520 src_info[VFE_PIX_0].raw_stream_count > 0) ? 1 : 0);
1522 ((vfe_dev->axi_data.
1523 src_info[VFE_PIX_0].stream_count > 0) ? 1 : 0);
1524 val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
1526 val = val | bus_en << 7 | vfe_en << 6;
1527 msm_camera_io_w(val, vfe_dev->vfe_base + 0x2F8);
1529 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1530 msm_camera_io_w(1, vfe_dev->vfe_base + 0x93C);
1531 msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x2F4);
1532 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2F4);
1533 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1;
1534 } else if (update_state == DISABLE_CAMIF ||
1535 DISABLE_CAMIF_IMMEDIATELY == update_state) {
1538 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1539 update_state = DISABLE_CAMIF;
1540 msm_vfe40_config_irq(vfe_dev, 0, 0x81,
1541 MSM_ISP_IRQ_DISABLE);
1542 val = msm_camera_io_r(vfe_dev->vfe_base + 0x464);
1543 /* disable danger signal */
1544 msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464);
1545 msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6),
1546 vfe_dev->vfe_base + 0x2F4);
1547 if (readl_poll_timeout_atomic(vfe_dev->vfe_base + 0x31C,
1548 poll_val, poll_val & 0x80000000, 1000, 2000000))
1549 pr_err("%s: camif disable failed %x\n",
1550 __func__, poll_val);
1551 vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
1553 if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
1554 msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C);
1555 msm_camera_io_w(0, vfe_dev->vfe_base + 0x30);
1556 msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34);
1557 msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24);
1558 msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask,
1564 static void msm_vfe40_cfg_rdi_reg(
1565 struct vfe_device *vfe_dev, struct msm_vfe_rdi_cfg *rdi_cfg,
1566 enum msm_vfe_input_src input_src)
1568 uint8_t rdi = input_src - VFE_RAW_0;
1569 uint32_t rdi_reg_cfg;
1570 rdi_reg_cfg = msm_camera_io_r(
1571 vfe_dev->vfe_base + VFE40_RDI_BASE(0));
1572 rdi_reg_cfg &= ~(BIT(16 + rdi));
1573 rdi_reg_cfg |= rdi_cfg->frame_based << (16 + rdi);
1574 msm_camera_io_w(rdi_reg_cfg,
1575 vfe_dev->vfe_base + VFE40_RDI_BASE(0));
1577 rdi_reg_cfg = msm_camera_io_r(
1578 vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
1579 rdi_reg_cfg &= 0x70003;
1580 rdi_reg_cfg |= (rdi * 3) << 28 | rdi_cfg->cid << 4 | 0x4;
1582 rdi_reg_cfg, vfe_dev->vfe_base + VFE40_RDI_BASE(rdi));
1585 static void msm_vfe40_axi_cfg_wm_reg(
1586 struct vfe_device *vfe_dev,
1587 struct msm_vfe_axi_stream *stream_info,
1591 uint32_t burst_len, wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION;
1592 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1595 wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
1597 if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
1598 vfe_dev->vfe_hw_version == VFE40_8939_VERSION) {
1599 burst_len = VFE40_BURST_LEN_8916_VERSION;
1600 wm_bit_shift = VFE40_WM_BIT_SHIFT;
1601 } else if (vfe_dev->vfe_hw_version == VFE40_8952_VERSION) {
1602 burst_len = VFE40_BURST_LEN_8952_VERSION;
1603 wm_bit_shift = VFE40_WM_BIT_SHIFT;
1604 } else if (vfe_dev->vfe_hw_version == VFE40_8976_VERSION ||
1605 vfe_dev->vfe_hw_version == VFE40_8937_VERSION ||
1606 vfe_dev->vfe_hw_version == VFE40_8917_VERSION ||
1607 vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
1608 burst_len = VFE40_BURST_LEN_8952_VERSION;
1609 wm_bit_shift = VFE40_WM_BIT_SHIFT_8976_VERSION;
1611 burst_len = VFE40_BURST_LEN;
1614 if (!stream_info->frame_based) {
1615 msm_camera_io_w(0x0, vfe_dev->vfe_base + wm_base);
1618 ((msm_isp_cal_word_per_line(
1619 stream_info->output_format,
1620 stream_info->plane_cfg[vfe_idx][plane_idx].
1621 output_width)+1)/2 - 1) << 16 |
1622 (stream_info->plane_cfg[vfe_idx][plane_idx].
1624 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
1628 msm_isp_cal_word_per_line(stream_info->output_format,
1629 stream_info->plane_cfg[vfe_idx][
1630 plane_idx].output_stride) << 16 |
1631 (stream_info->plane_cfg[vfe_idx][
1632 plane_idx].output_height - 1) << wm_bit_shift |
1634 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1636 msm_camera_io_w(0x2, vfe_dev->vfe_base + wm_base);
1638 msm_isp_cal_word_per_line(stream_info->output_format,
1639 stream_info->plane_cfg[vfe_idx][
1640 plane_idx].output_width) << 16 |
1641 (stream_info->plane_cfg[vfe_idx][
1642 plane_idx].output_height - 1) << 4 |
1644 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1647 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1648 msm_camera_io_w(0xFFFFFFFF,
1649 vfe_dev->vfe_base + wm_base + 0x20);
1650 /* TD: Add IRQ subsample pattern */
1654 static void msm_vfe40_axi_clear_wm_reg(
1655 struct vfe_device *vfe_dev,
1656 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
1659 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1662 wm_base = VFE40_WM_BASE(stream_info->wm[vfe_idx][plane_idx]);
1664 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0xC);
1666 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x14);
1668 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x18);
1669 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1670 msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x20);
1674 static void msm_vfe40_axi_cfg_wm_xbar_reg(
1675 struct vfe_device *vfe_dev,
1676 struct msm_vfe_axi_stream *stream_info,
1679 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1680 struct msm_vfe_axi_plane_cfg *plane_cfg;
1682 uint32_t xbar_cfg = 0;
1683 uint32_t xbar_reg_cfg = 0;
1685 plane_cfg = &stream_info->plane_cfg[vfe_idx][plane_idx];
1686 wm = stream_info->wm[vfe_idx][plane_idx];
1688 switch (stream_info->stream_src) {
1690 case PIX_VIEWFINDER: {
1691 if (plane_cfg->output_plane_format != CRCB_PLANE &&
1692 plane_cfg->output_plane_format != CBCR_PLANE) {
1693 /*SINGLE_STREAM_SEL*/
1694 xbar_cfg |= plane_cfg->output_plane_format << 8;
1696 switch (stream_info->output_format) {
1697 case V4L2_PIX_FMT_NV12:
1698 case V4L2_PIX_FMT_NV14:
1699 case V4L2_PIX_FMT_NV16:
1700 case V4L2_PIX_FMT_NV24:
1701 xbar_cfg |= 0x3 << 4; /*PAIR_STREAM_SWAP_CTRL*/
1704 xbar_cfg |= 0x1 << 1; /*PAIR_STREAM_EN*/
1706 if (stream_info->stream_src == PIX_VIEWFINDER)
1707 xbar_cfg |= 0x1; /*VIEW_STREAM_EN*/
1726 pr_err("%s: Invalid stream src\n", __func__);
1730 msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1731 xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
1732 xbar_reg_cfg |= (xbar_cfg << VFE40_XBAR_SHIFT(wm));
1733 msm_camera_io_w(xbar_reg_cfg,
1734 vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1738 static void msm_vfe40_axi_clear_wm_xbar_reg(
1739 struct vfe_device *vfe_dev,
1740 struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx)
1742 int vfe_idx = msm_isp_get_vfe_idx_for_stream(vfe_dev, stream_info);
1744 uint32_t xbar_reg_cfg = 0;
1746 wm = stream_info->wm[vfe_idx][plane_idx];
1749 msm_camera_io_r(vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1750 xbar_reg_cfg &= ~(0xFFFF << VFE40_XBAR_SHIFT(wm));
1751 msm_camera_io_w(xbar_reg_cfg,
1752 vfe_dev->vfe_base + VFE40_XBAR_BASE(wm));
1755 static void msm_vfe40_read_wm_ping_pong_addr(
1756 struct vfe_device *vfe_dev)
1758 msm_camera_io_dump(vfe_dev->vfe_base +
1759 (VFE40_WM_BASE(0) & 0xFFFFFFF0), 0x200, 1);
1762 static void msm_vfe40_update_ping_pong_addr(
1763 void __iomem *vfe_base,
1764 uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr,
1767 uint32_t paddr32 = (paddr & 0xFFFFFFFF);
1768 msm_camera_io_w(paddr32, vfe_base +
1769 VFE40_PING_PONG_BASE(wm_idx, pingpong_bit));
1772 static void msm_vfe40_set_halt_restart_mask(struct vfe_device *vfe_dev)
1774 msm_vfe40_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET);
1777 static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev,
1781 enum msm_vfe_input_src i;
1782 struct msm_isp_timestamp ts;
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 init_completion(&vfe_dev->halt_complete);
1800 /* Halt AXI Bus Bridge */
1801 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
1802 rc = wait_for_completion_interruptible_timeout(
1803 &vfe_dev->halt_complete, msecs_to_jiffies(500));
1805 pr_err("%s:VFE%d halt timeout rc=%d\n", __func__,
1806 vfe_dev->pdev->id, rc);
1808 /* Halt AXI Bus Bridge */
1809 msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
1815 static void msm_vfe40_axi_restart(struct vfe_device *vfe_dev,
1816 uint32_t blocking, uint32_t enable_camif)
1818 msm_vfe40_config_irq(vfe_dev, vfe_dev->recovery_irq0_mask,
1819 vfe_dev->recovery_irq1_mask,
1820 MSM_ISP_IRQ_ENABLE);
1821 msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318);
1824 msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
1826 vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX);
1827 memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info));
1828 atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW);
1830 vfe_dev->hw_info->vfe_ops.core_ops.
1831 update_camif_state(vfe_dev, ENABLE_CAMIF);
1834 static uint32_t msm_vfe40_get_wm_mask(
1835 uint32_t irq_status0, uint32_t irq_status1)
1837 return (irq_status0 >> 8) & 0x7F;
1840 static uint32_t msm_vfe40_get_comp_mask(
1841 uint32_t irq_status0, uint32_t irq_status1)
1843 return (irq_status0 >> 25) & 0xF;
1846 static uint32_t msm_vfe40_get_pingpong_status(
1847 struct vfe_device *vfe_dev)
1849 return msm_camera_io_r(vfe_dev->vfe_base + 0x268);
1852 static int msm_vfe40_get_stats_idx(enum msm_isp_stats_type stats_type)
1854 switch (stats_type) {
1855 case MSM_ISP_STATS_BE:
1857 case MSM_ISP_STATS_BG:
1859 case MSM_ISP_STATS_BF:
1861 case MSM_ISP_STATS_AWB:
1863 case MSM_ISP_STATS_RS:
1865 case MSM_ISP_STATS_CS:
1867 case MSM_ISP_STATS_IHIST:
1869 case MSM_ISP_STATS_BHIST:
1872 pr_err("%s: Invalid stats type\n", __func__);
1877 static int msm_vfe40_stats_check_streams(
1878 struct msm_vfe_stats_stream *stream_info)
1883 static void msm_vfe40_stats_cfg_comp_mask(struct vfe_device *vfe_dev,
1884 uint32_t stats_mask, uint8_t request_comp_index, uint8_t enable)
1886 uint32_t comp_mask_reg, mask_bf_scale;
1887 atomic_t *stats_comp_mask;
1888 struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
1890 if (vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask < 1)
1893 if (request_comp_index >= MAX_NUM_STATS_COMP_MASK) {
1894 pr_err("%s: num of comp masks %d exceed max %d\n",
1895 __func__, request_comp_index,
1896 MAX_NUM_STATS_COMP_MASK);
1900 if (vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask >
1901 MAX_NUM_STATS_COMP_MASK) {
1902 pr_err("%s: num of comp masks %d exceed max %d\n",
1904 vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask,
1905 MAX_NUM_STATS_COMP_MASK);
1909 stats_mask = stats_mask & 0xFF;
1910 mask_bf_scale = stats_mask;
1912 stats_comp_mask = &stats_data->stats_comp_mask[request_comp_index];
1913 comp_mask_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x44);
1916 comp_mask_reg |= mask_bf_scale << (16 + request_comp_index * 8);
1917 atomic_set(stats_comp_mask, stats_mask |
1918 atomic_read(stats_comp_mask));
1919 msm_vfe40_config_irq(vfe_dev,
1920 1 << (request_comp_index + 29), 0,
1921 MSM_ISP_IRQ_ENABLE);
1923 if (!(atomic_read(stats_comp_mask) & stats_mask))
1925 atomic_set(stats_comp_mask,
1926 ~stats_mask & atomic_read(stats_comp_mask));
1927 comp_mask_reg &= ~(mask_bf_scale <<
1928 (16 + request_comp_index * 8));
1929 msm_vfe40_config_irq(vfe_dev,
1930 1 << (request_comp_index + 29), 0,
1931 MSM_ISP_IRQ_DISABLE);
1933 msm_camera_io_w(comp_mask_reg, vfe_dev->vfe_base + 0x44);
1935 ISP_DBG("%s: comp_mask_reg: %x comp mask0 %x mask1: %x\n",
1936 __func__, comp_mask_reg,
1937 atomic_read(&stats_data->stats_comp_mask[0]),
1938 atomic_read(&stats_data->stats_comp_mask[1]));
1943 static void msm_vfe40_stats_cfg_wm_irq_mask(
1944 struct vfe_device *vfe_dev,
1945 struct msm_vfe_stats_stream *stream_info)
1947 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1950 msm_vfe40_config_irq(vfe_dev,
1951 1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16), 0,
1952 MSM_ISP_IRQ_ENABLE);
1955 static void msm_vfe40_stats_clear_wm_irq_mask(
1956 struct vfe_device *vfe_dev,
1957 struct msm_vfe_stats_stream *stream_info)
1959 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1962 msm_vfe40_config_irq(vfe_dev,
1963 (1 << (STATS_IDX(stream_info->stream_handle[vfe_idx]) + 16)), 0,
1964 MSM_ISP_IRQ_DISABLE);
1967 static void msm_vfe40_stats_cfg_wm_reg(
1968 struct vfe_device *vfe_dev,
1969 struct msm_vfe_stats_stream *stream_info)
1971 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1974 uint32_t stats_base;
1976 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
1977 stats_base = VFE40_STATS_BASE(stats_idx);
1979 msm_camera_io_w((stream_info->framedrop_period - 1) << 2,
1980 vfe_dev->vfe_base + stats_base + 0x8);
1981 /*WR_IRQ_FRAMEDROP_PATTERN*/
1982 msm_camera_io_w(stream_info->framedrop_pattern,
1983 vfe_dev->vfe_base + stats_base + 0x10);
1984 /*WR_IRQ_SUBSAMPLE_PATTERN*/
1985 msm_camera_io_w(0xFFFFFFFF,
1986 vfe_dev->vfe_base + stats_base + 0x14);
1989 static void msm_vfe40_stats_clear_wm_reg(
1990 struct vfe_device *vfe_dev,
1991 struct msm_vfe_stats_stream *stream_info)
1993 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
1997 uint32_t stats_base;
1999 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
2000 stats_base = VFE40_STATS_BASE(stats_idx);
2003 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x8);
2004 /*WR_IRQ_FRAMEDROP_PATTERN*/
2005 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x10);
2006 /*WR_IRQ_SUBSAMPLE_PATTERN*/
2007 msm_camera_io_w(val, vfe_dev->vfe_base + stats_base + 0x14);
2010 static void msm_vfe40_stats_cfg_ub(struct vfe_device *vfe_dev)
2014 uint32_t stats_burst_len;
2015 uint32_t ub_size[VFE40_NUM_STATS_TYPE] = {
2016 64, /*MSM_ISP_STATS_BE*/
2017 128, /*MSM_ISP_STATS_BG*/
2018 128, /*MSM_ISP_STATS_BF*/
2019 16, /*MSM_ISP_STATS_AWB*/
2020 8, /*MSM_ISP_STATS_RS*/
2021 16, /*MSM_ISP_STATS_CS*/
2022 16, /*MSM_ISP_STATS_IHIST*/
2023 16, /*MSM_ISP_STATS_BHIST*/
2026 if (vfe_dev->vfe_hw_version == VFE40_8916_VERSION ||
2027 vfe_dev->vfe_hw_version == VFE40_8939_VERSION ||
2028 vfe_dev->vfe_hw_version == VFE40_8937_VERSION ||
2029 vfe_dev->vfe_hw_version == VFE40_8917_VERSION ||
2030 vfe_dev->vfe_hw_version == VFE40_8953_VERSION) {
2031 stats_burst_len = VFE40_STATS_BURST_LEN_8916_VERSION;
2032 ub_offset = VFE40_UB_SIZE_8916;
2033 } else if (vfe_dev->vfe_hw_version == VFE40_8952_VERSION ||
2034 vfe_dev->vfe_hw_version == VFE40_8976_VERSION) {
2035 stats_burst_len = VFE40_STATS_BURST_LEN_8916_VERSION;
2036 ub_offset = VFE40_UB_SIZE_8952;
2038 stats_burst_len = VFE40_STATS_BURST_LEN;
2039 ub_offset = VFE40_UB_SIZE;
2042 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2043 ub_offset -= ub_size[i];
2044 msm_camera_io_w(stats_burst_len << 30 |
2045 ub_offset << 16 | (ub_size[i] - 1),
2046 vfe_dev->vfe_base + VFE40_STATS_BASE(i) + 0xC);
2050 static void msm_vfe40_stats_update_cgc_override(struct vfe_device *vfe_dev,
2051 uint32_t stats_mask, uint8_t enable)
2054 uint32_t module_cfg, cgc_mask = 0;
2056 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2057 if ((stats_mask >> i) & 0x1) {
2060 cgc_mask |= (1 << 8);
2063 cgc_mask |= (1 << 10);
2066 cgc_mask |= (1 << 9);
2068 case STATS_IDX_BHIST:
2069 cgc_mask |= (1 << 15);
2072 cgc_mask |= (1 << 11);
2075 cgc_mask |= (1 << 12);
2078 cgc_mask |= (1 << 13);
2080 case STATS_IDX_IHIST:
2081 cgc_mask |= (1 << 14);
2084 pr_err("%s: Invalid stats mask\n", __func__);
2091 module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x974);
2093 module_cfg |= cgc_mask;
2095 module_cfg &= ~cgc_mask;
2096 msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x974);
2099 static bool msm_vfe40_is_module_cfg_lock_needed(
2100 uint32_t reg_offset)
2102 if (reg_offset == 0x18)
2108 static void msm_vfe40_stats_enable_module(struct vfe_device *vfe_dev,
2109 uint32_t stats_mask, uint8_t enable)
2112 uint32_t module_cfg, module_cfg_mask = 0;
2113 unsigned long flags;
2115 for (i = 0; i < VFE40_NUM_STATS_TYPE; i++) {
2116 if ((stats_mask >> i) & 0x1) {
2124 module_cfg_mask |= 1 << (5 + i);
2127 module_cfg_mask |= 1 << 15;
2130 module_cfg_mask |= 1 << 18;
2133 pr_err("%s: Invalid stats mask\n", __func__);
2140 * For vfe40 stats and other modules share module_cfg register.
2141 * Hence need to Grab lock.
2143 spin_lock_irqsave(&vfe_dev->shared_data_lock, flags);
2144 module_cfg = msm_camera_io_r(vfe_dev->vfe_base + 0x18);
2146 module_cfg |= module_cfg_mask;
2148 module_cfg &= ~module_cfg_mask;
2149 msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x18);
2150 spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
2153 static void msm_vfe40_stats_update_ping_pong_addr(
2154 struct vfe_device *vfe_dev, struct msm_vfe_stats_stream *stream_info,
2155 uint32_t pingpong_status, dma_addr_t paddr, uint32_t buf_sz)
2157 void __iomem *vfe_base = vfe_dev->vfe_base;
2158 int vfe_idx = msm_isp_get_vfe_idx_for_stats_stream(vfe_dev,
2160 uint32_t paddr32 = (paddr & 0xFFFFFFFF);
2163 stats_idx = STATS_IDX(stream_info->stream_handle[vfe_idx]);
2164 msm_camera_io_w(paddr32, vfe_base +
2165 VFE40_STATS_PING_PONG_BASE(stats_idx, pingpong_status));
2168 static uint32_t msm_vfe40_stats_get_wm_mask(
2169 uint32_t irq_status0, uint32_t irq_status1)
2171 return (irq_status0 >> 16) & 0xFF;
2174 static uint32_t msm_vfe40_stats_get_comp_mask(
2175 uint32_t irq_status0, uint32_t irq_status1)
2177 return (irq_status0 >> 29) & 0x3;
2180 static uint32_t msm_vfe40_stats_get_frame_id(
2181 struct vfe_device *vfe_dev)
2183 return vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
2186 static void msm_vfe40_get_error_mask(
2187 uint32_t *error_mask0, uint32_t *error_mask1)
2189 *error_mask0 = 0x00000000;
2190 *error_mask1 = 0x00FFFEFF;
2193 static void msm_vfe40_get_overflow_mask(uint32_t *overflow_mask)
2195 *overflow_mask = 0x00FFFE7E;
2198 static void msm_vfe40_get_rdi_wm_mask(struct vfe_device *vfe_dev,
2199 uint32_t *rdi_wm_mask)
2201 *rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask;
2204 static void msm_vfe40_get_irq_mask(struct vfe_device *vfe_dev,
2205 uint32_t *irq0_mask, uint32_t *irq1_mask)
2207 *irq0_mask = vfe_dev->irq0_mask;
2208 *irq1_mask = vfe_dev->irq1_mask;
2211 static void msm_vfe40_get_halt_restart_mask(uint32_t *irq0_mask,
2212 uint32_t *irq1_mask)
2214 *irq0_mask = BIT(31);
2215 *irq1_mask = BIT(8);
2218 static struct msm_vfe_axi_hardware_info msm_vfe40_axi_hw_info = {
2222 .num_rdi_master = 3,
2224 .scratch_buf_range = SZ_32M + SZ_4M,
2227 static struct msm_vfe_stats_hardware_info msm_vfe40_stats_hw_info = {
2228 .stats_capability_mask =
2229 1 << MSM_ISP_STATS_BE | 1 << MSM_ISP_STATS_BF |
2230 1 << MSM_ISP_STATS_BG | 1 << MSM_ISP_STATS_BHIST |
2231 1 << MSM_ISP_STATS_AWB | 1 << MSM_ISP_STATS_IHIST |
2232 1 << MSM_ISP_STATS_RS | 1 << MSM_ISP_STATS_CS,
2233 .stats_ping_pong_offset = stats_pingpong_offset_map,
2234 .num_stats_type = VFE40_NUM_STATS_TYPE,
2235 .num_stats_comp_mask = 2,
2238 struct msm_vfe_hardware_info vfe40_hw_info = {
2240 .num_iommu_secure_ctx = 1,
2241 .vfe_clk_idx = VFE40_CLK_IDX,
2242 .runtime_axi_update = 0,
2247 .read_and_clear_irq_status =
2248 msm_vfe40_read_and_clear_irq_status,
2249 .read_irq_status = msm_vfe40_read_irq_status,
2250 .process_camif_irq = msm_vfe40_process_input_irq,
2251 .process_reset_irq = msm_vfe40_process_reset_irq,
2252 .process_halt_irq = msm_vfe40_process_halt_irq,
2253 .process_reset_irq = msm_vfe40_process_reset_irq,
2254 .process_reg_update = msm_vfe40_process_reg_update,
2255 .process_axi_irq = msm_isp_process_axi_irq,
2256 .process_stats_irq = msm_isp_process_stats_irq,
2257 .process_epoch_irq = msm_vfe40_process_epoch_irq,
2258 .config_irq = msm_vfe40_config_irq,
2259 .preprocess_camif_irq = msm_isp47_preprocess_camif_irq,
2262 .reload_wm = msm_vfe40_axi_reload_wm,
2263 .enable_wm = msm_vfe40_axi_enable_wm,
2264 .cfg_io_format = msm_vfe40_cfg_io_format,
2265 .cfg_comp_mask = msm_vfe40_axi_cfg_comp_mask,
2266 .clear_comp_mask = msm_vfe40_axi_clear_comp_mask,
2267 .cfg_wm_irq_mask = msm_vfe40_axi_cfg_wm_irq_mask,
2268 .clear_wm_irq_mask = msm_vfe40_axi_clear_wm_irq_mask,
2269 .cfg_framedrop = msm_vfe40_cfg_framedrop,
2270 .clear_framedrop = msm_vfe40_clear_framedrop,
2271 .cfg_wm_reg = msm_vfe40_axi_cfg_wm_reg,
2272 .clear_wm_reg = msm_vfe40_axi_clear_wm_reg,
2273 .cfg_wm_xbar_reg = msm_vfe40_axi_cfg_wm_xbar_reg,
2274 .clear_wm_xbar_reg = msm_vfe40_axi_clear_wm_xbar_reg,
2275 .cfg_ub = msm_vfe47_cfg_axi_ub,
2276 .read_wm_ping_pong_addr =
2277 msm_vfe40_read_wm_ping_pong_addr,
2278 .update_ping_pong_addr =
2279 msm_vfe40_update_ping_pong_addr,
2280 .get_comp_mask = msm_vfe40_get_comp_mask,
2281 .get_wm_mask = msm_vfe40_get_wm_mask,
2282 .get_pingpong_status = msm_vfe40_get_pingpong_status,
2283 .halt = msm_vfe40_axi_halt,
2284 .restart = msm_vfe40_axi_restart,
2285 .update_cgc_override =
2286 msm_vfe40_axi_update_cgc_override,
2287 .ub_reg_offset = msm_vfe40_ub_reg_offset,
2288 .get_ub_size = msm_vfe40_get_ub_size,
2291 .reg_update = msm_vfe40_reg_update,
2292 .cfg_input_mux = msm_vfe40_cfg_input_mux,
2293 .update_camif_state = msm_vfe40_update_camif_state,
2294 .start_fetch_eng = msm_vfe40_start_fetch_engine,
2295 .cfg_rdi_reg = msm_vfe40_cfg_rdi_reg,
2296 .reset_hw = msm_vfe40_reset_hardware,
2297 .init_hw = msm_vfe47_init_hardware,
2298 .init_hw_reg = msm_vfe40_init_hardware_reg,
2299 .clear_status_reg = msm_vfe40_clear_status_reg,
2300 .release_hw = msm_vfe47_release_hardware,
2301 .get_error_mask = msm_vfe40_get_error_mask,
2302 .get_overflow_mask = msm_vfe40_get_overflow_mask,
2303 .get_rdi_wm_mask = msm_vfe40_get_rdi_wm_mask,
2304 .get_irq_mask = msm_vfe40_get_irq_mask,
2305 .get_halt_restart_mask =
2306 msm_vfe40_get_halt_restart_mask,
2307 .process_error_status = msm_vfe40_process_error_status,
2308 .is_module_cfg_lock_needed =
2309 msm_vfe40_is_module_cfg_lock_needed,
2310 .ahb_clk_cfg = NULL,
2311 .start_fetch_eng_multi_pass =
2312 msm_vfe40_start_fetch_engine_multi_pass,
2313 .set_halt_restart_mask =
2314 msm_vfe40_set_halt_restart_mask,
2315 .set_bus_err_ign_mask = NULL,
2316 .get_bus_err_mask = NULL,
2319 .get_stats_idx = msm_vfe40_get_stats_idx,
2320 .check_streams = msm_vfe40_stats_check_streams,
2321 .cfg_comp_mask = msm_vfe40_stats_cfg_comp_mask,
2322 .cfg_wm_irq_mask = msm_vfe40_stats_cfg_wm_irq_mask,
2323 .clear_wm_irq_mask = msm_vfe40_stats_clear_wm_irq_mask,
2324 .cfg_wm_reg = msm_vfe40_stats_cfg_wm_reg,
2325 .clear_wm_reg = msm_vfe40_stats_clear_wm_reg,
2326 .cfg_ub = msm_vfe40_stats_cfg_ub,
2327 .enable_module = msm_vfe40_stats_enable_module,
2328 .update_ping_pong_addr =
2329 msm_vfe40_stats_update_ping_pong_addr,
2330 .get_comp_mask = msm_vfe40_stats_get_comp_mask,
2331 .get_wm_mask = msm_vfe40_stats_get_wm_mask,
2332 .get_frame_id = msm_vfe40_stats_get_frame_id,
2333 .get_pingpong_status = msm_vfe40_get_pingpong_status,
2334 .update_cgc_override =
2335 msm_vfe40_stats_update_cgc_override,
2336 .enable_stats_wm = NULL,
2339 .get_platform_data = msm_vfe47_get_platform_data,
2340 .enable_regulators = msm_vfe47_enable_regulators,
2341 .get_regulators = msm_vfe47_get_regulators,
2342 .put_regulators = msm_vfe47_put_regulators,
2343 .enable_clks = msm_vfe47_enable_clks,
2344 .get_clks = msm_vfe47_get_clks,
2345 .put_clks = msm_vfe47_put_clks,
2346 .get_clk_rates = msm_vfe47_get_clk_rates,
2347 .get_max_clk_rate = msm_vfe47_get_max_clk_rate,
2348 .set_clk_rate = msm_vfe47_set_clk_rate,
2349 .init_bw_mgr = msm_vfe47_init_bandwidth_mgr,
2350 .deinit_bw_mgr = msm_vfe47_deinit_bandwidth_mgr,
2351 .update_bw = msm_vfe47_update_bandwidth,
2354 .dmi_reg_offset = 0x918,
2355 .axi_hw_info = &msm_vfe40_axi_hw_info,
2356 .stats_hw_info = &msm_vfe40_stats_hw_info,
2357 .regulator_names = {"vdd"},
2359 EXPORT_SYMBOL(vfe40_hw_info);
2361 static const struct of_device_id msm_vfe40_dt_match[] = {
2363 .compatible = "qcom,vfe40",
2364 .data = &vfe40_hw_info,
2369 MODULE_DEVICE_TABLE(of, msm_vfe40_dt_match);
2371 static struct platform_driver vfe40_driver = {
2372 .probe = vfe_hw_probe,
2374 .name = "msm_vfe40",
2375 .owner = THIS_MODULE,
2376 .of_match_table = msm_vfe40_dt_match,
2380 static int __init msm_vfe40_init_module(void)
2382 return platform_driver_register(&vfe40_driver);
2385 static void __exit msm_vfe40_exit_module(void)
2387 platform_driver_unregister(&vfe40_driver);
2390 module_init(msm_vfe40_init_module);
2391 module_exit(msm_vfe40_exit_module);
2392 MODULE_DESCRIPTION("MSM VFE40 driver");
2393 MODULE_LICENSE("GPL v2");