14e1abf66STodor Tomov // SPDX-License-Identifier: GPL-2.0
24e1abf66STodor Tomov /*
34e1abf66STodor Tomov * camss-vfe-4-7.c
44e1abf66STodor Tomov *
54e1abf66STodor Tomov * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.7
64e1abf66STodor Tomov *
74e1abf66STodor Tomov * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
84e1abf66STodor Tomov * Copyright (C) 2015-2018 Linaro Ltd.
94e1abf66STodor Tomov */
104e1abf66STodor Tomov
112f6f8af6SRobert Foss #include <linux/device.h>
124e1abf66STodor Tomov #include <linux/interrupt.h>
133799eca5SArnd Bergmann #include <linux/io.h>
144e1abf66STodor Tomov #include <linux/iopoll.h>
154e1abf66STodor Tomov
16c3177cb0SRobert Foss #include "camss.h"
174e1abf66STodor Tomov #include "camss-vfe.h"
18633b388fSRobert Foss #include "camss-vfe-gen1.h"
19633b388fSRobert Foss
204e1abf66STodor Tomov
214e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD 0x018
224e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_CORE BIT(0)
234e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1)
244e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2)
254e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3)
264e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_REGISTER BIT(4)
274e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_PM BIT(5)
284e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(6)
294e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(7)
304e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_DSP BIT(8)
314e1abf66STodor Tomov #define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC BIT(9)
324e1abf66STodor Tomov
334e1abf66STodor Tomov #define VFE_0_MODULE_LENS_EN 0x040
344e1abf66STodor Tomov #define VFE_0_MODULE_LENS_EN_DEMUX BIT(2)
354e1abf66STodor Tomov #define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE BIT(3)
364e1abf66STodor Tomov
374e1abf66STodor Tomov #define VFE_0_MODULE_ZOOM_EN 0x04c
384e1abf66STodor Tomov #define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1)
394e1abf66STodor Tomov #define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2)
40312e1c85STodor Tomov #define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF BIT(9)
414e1abf66STodor Tomov
424e1abf66STodor Tomov #define VFE_0_CORE_CFG 0x050
434e1abf66STodor Tomov #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4
444e1abf66STodor Tomov #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5
454e1abf66STodor Tomov #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6
464e1abf66STodor Tomov #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7
474e1abf66STodor Tomov #define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN BIT(4)
484e1abf66STodor Tomov
494e1abf66STodor Tomov #define VFE_0_IRQ_CMD 0x058
504e1abf66STodor Tomov #define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0)
514e1abf66STodor Tomov
524e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0 0x05c
534e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0)
544e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1)
554e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) BIT((n) + 5)
564e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \
574e1abf66STodor Tomov ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
584e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8)
594e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25)
604e1abf66STodor Tomov #define VFE_0_IRQ_MASK_0_RESET_ACK BIT(31)
614e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1 0x060
624e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1_CAMIF_ERROR BIT(0)
634e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1_VIOLATION BIT(7)
644e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK BIT(8)
654e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9)
664e1abf66STodor Tomov #define VFE_0_IRQ_MASK_1_RDIn_SOF(n) BIT((n) + 29)
674e1abf66STodor Tomov
684e1abf66STodor Tomov #define VFE_0_IRQ_CLEAR_0 0x064
694e1abf66STodor Tomov #define VFE_0_IRQ_CLEAR_1 0x068
704e1abf66STodor Tomov
714e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0 0x06c
724e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_CAMIF_SOF BIT(0)
734e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5)
744e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \
754e1abf66STodor Tomov ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
764e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8)
774e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25)
784e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_0_RESET_ACK BIT(31)
794e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_1 0x070
804e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_1_VIOLATION BIT(7)
814e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK BIT(8)
824e1abf66STodor Tomov #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) BIT((n) + 29)
834e1abf66STodor Tomov
844e1abf66STodor Tomov #define VFE_0_IRQ_COMPOSITE_MASK_0 0x074
854e1abf66STodor Tomov #define VFE_0_VIOLATION_STATUS 0x07c
864e1abf66STodor Tomov
874e1abf66STodor Tomov #define VFE_0_BUS_CMD 0x80
884e1abf66STodor Tomov #define VFE_0_BUS_CMD_Mx_RLD_CMD(x) BIT(x)
894e1abf66STodor Tomov
904e1abf66STodor Tomov #define VFE_0_BUS_CFG 0x084
914e1abf66STodor Tomov
924e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x(x) (0x90 + 0x4 * ((x) / 2))
934e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(2)
94312e1c85STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN BIT(3)
95312e1c85STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA (0x1 << 4)
96312e1c85STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER (0x2 << 4)
974e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4)
984e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8
994e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0x0
1004e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 0xc
1014e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 0xd
1024e1abf66STodor Tomov #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 0xe
1034e1abf66STodor Tomov
1044e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x0a0 + 0x2c * (n))
1054e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0
1064e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x0a4 + 0x2c * (n))
1074e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x0ac + 0x2c * (n))
1084e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x0b4 + 0x2c * (n))
1094e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT 1
1104e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2
1114e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1f << 2)
1124e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x0b8 + 0x2c * (n))
1134e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16
1144e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x0bc + 0x2c * (n))
1154e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x0c0 + 0x2c * (n))
1164e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \
1174e1abf66STodor Tomov (0x0c4 + 0x2c * (n))
1184e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \
1194e1abf66STodor Tomov (0x0c8 + 0x2c * (n))
1204e1abf66STodor Tomov #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff
1214e1abf66STodor Tomov
1224e1abf66STodor Tomov #define VFE_0_BUS_PING_PONG_STATUS 0x338
1234e1abf66STodor Tomov
1244e1abf66STodor Tomov #define VFE_0_BUS_BDG_CMD 0x400
1254e1abf66STodor Tomov #define VFE_0_BUS_BDG_CMD_HALT_REQ 1
1264e1abf66STodor Tomov
1274e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_0 0x404
1284e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa9aaa9
1294e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_1 0x408
1304e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_2 0x40c
1314e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_3 0x410
1324e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_4 0x414
1334e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_5 0x418
1344e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_6 0x41c
1354e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_7 0x420
1364e1abf66STodor Tomov #define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0001aaa9
1374e1abf66STodor Tomov
13840296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5
13940296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5
14040296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55
14140296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55
14240296e71SAngeloGioacchino Del Regno
1434e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_0 0x424
1444e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_0_CFG 0xcccc0011
1454e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_1 0x428
1464e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_2 0x42c
1474e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_3 0x430
1484e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_4 0x434
1494e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_5 0x438
1504e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_6 0x43c
1514e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_7 0x440
1524e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_8 0x444
1534e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_9 0x448
1544e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_10 0x44c
1554e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_11 0x450
1564e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_12 0x454
1574e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_13 0x458
1584e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_14 0x45c
1594e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_15 0x460
1604e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_16 0x464
1614e1abf66STodor Tomov #define VFE_0_BUS_BDG_DS_CFG_16_CFG 0x40000103
1624e1abf66STodor Tomov
16340296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_DS_CFG_0_CFG 0xcccc1111
16440296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_BDG_DS_CFG_16_CFG 0x00000110
16540296e71SAngeloGioacchino Del Regno
1664e1abf66STodor Tomov #define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x)))
1674e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28
1684e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28)
1694e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4
1704e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4)
1714e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_RDI_EN_BIT BIT(2)
1724e1abf66STodor Tomov #define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3
1734e1abf66STodor Tomov
1744e1abf66STodor Tomov #define VFE_0_CAMIF_CMD 0x478
1754e1abf66STodor Tomov #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0
1764e1abf66STodor Tomov #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1
1774e1abf66STodor Tomov #define VFE_0_CAMIF_CMD_NO_CHANGE 3
1784e1abf66STodor Tomov #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS BIT(2)
1794e1abf66STodor Tomov #define VFE_0_CAMIF_CFG 0x47c
1804e1abf66STodor Tomov #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN BIT(6)
1814e1abf66STodor Tomov #define VFE_0_CAMIF_FRAME_CFG 0x484
1824e1abf66STodor Tomov #define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488
1834e1abf66STodor Tomov #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c
1844e1abf66STodor Tomov #define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490
1854e1abf66STodor Tomov #define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498
1864e1abf66STodor Tomov #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c
1874e1abf66STodor Tomov #define VFE_0_CAMIF_STATUS 0x4a4
1884e1abf66STodor Tomov #define VFE_0_CAMIF_STATUS_HALT BIT(31)
1894e1abf66STodor Tomov
1904e1abf66STodor Tomov #define VFE_0_REG_UPDATE 0x4ac
1914e1abf66STodor Tomov #define VFE_0_REG_UPDATE_RDIn(n) BIT(1 + (n))
1924e1abf66STodor Tomov #define VFE_0_REG_UPDATE_line_n(n) \
1934e1abf66STodor Tomov ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
1944e1abf66STodor Tomov
1954e1abf66STodor Tomov #define VFE_0_DEMUX_CFG 0x560
1964e1abf66STodor Tomov #define VFE_0_DEMUX_CFG_PERIOD 0x3
1974e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_0 0x564
1984e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0)
1994e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16)
2004e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_1 0x568
2014e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0)
2024e1abf66STodor Tomov #define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16)
2034e1abf66STodor Tomov #define VFE_0_DEMUX_EVEN_CFG 0x574
2044e1abf66STodor Tomov #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac
2054e1abf66STodor Tomov #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c
2064e1abf66STodor Tomov #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca
2074e1abf66STodor Tomov #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9
2084e1abf66STodor Tomov #define VFE_0_DEMUX_ODD_CFG 0x578
2094e1abf66STodor Tomov #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac
2104e1abf66STodor Tomov #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c
2114e1abf66STodor Tomov #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca
2124e1abf66STodor Tomov #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9
2134e1abf66STodor Tomov
2144e1abf66STodor Tomov #define VFE_0_SCALE_ENC_Y_CFG 0x91c
2154e1abf66STodor Tomov #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x920
2164e1abf66STodor Tomov #define VFE_0_SCALE_ENC_Y_H_PHASE 0x924
2174e1abf66STodor Tomov #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x934
2184e1abf66STodor Tomov #define VFE_0_SCALE_ENC_Y_V_PHASE 0x938
2194e1abf66STodor Tomov #define VFE_0_SCALE_ENC_CBCR_CFG 0x948
2204e1abf66STodor Tomov #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x94c
2214e1abf66STodor Tomov #define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x950
2224e1abf66STodor Tomov #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x960
2234e1abf66STodor Tomov #define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x964
2244e1abf66STodor Tomov
2254e1abf66STodor Tomov #define VFE_0_CROP_ENC_Y_WIDTH 0x974
2264e1abf66STodor Tomov #define VFE_0_CROP_ENC_Y_HEIGHT 0x978
2274e1abf66STodor Tomov #define VFE_0_CROP_ENC_CBCR_WIDTH 0x97c
2284e1abf66STodor Tomov #define VFE_0_CROP_ENC_CBCR_HEIGHT 0x980
2294e1abf66STodor Tomov
2304e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MAX_CFG 0x984
2314e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0)
2324e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8)
2334e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16)
2344e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MIN_CFG 0x988
2354e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0)
2364e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8)
2374e1abf66STodor Tomov #define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16)
2384e1abf66STodor Tomov
239312e1c85STodor Tomov #define VFE_0_REALIGN_BUF_CFG 0xaac
240312e1c85STodor Tomov #define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL BIT(2)
241312e1c85STodor Tomov #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3)
242312e1c85STodor Tomov #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4)
243312e1c85STodor Tomov
24440296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_IMAGE_MASTER_CMD 0xcec
24540296e71SAngeloGioacchino Del Regno #define VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(x) (2 * (x))
24640296e71SAngeloGioacchino Del Regno
2474e1abf66STodor Tomov #define CAMIF_TIMEOUT_SLEEP_US 1000
2484e1abf66STodor Tomov #define CAMIF_TIMEOUT_ALL_US 1000000
2494e1abf66STodor Tomov
2504e1abf66STodor Tomov #define MSM_VFE_VFE0_UB_SIZE 2047
2514e1abf66STodor Tomov #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
2524e1abf66STodor Tomov #define MSM_VFE_VFE1_UB_SIZE 1535
2534e1abf66STodor Tomov #define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3)
2544e1abf66STodor Tomov
vfe_get_ub_size(u8 vfe_id)255633b388fSRobert Foss static u16 vfe_get_ub_size(u8 vfe_id)
2564e1abf66STodor Tomov {
2574e1abf66STodor Tomov if (vfe_id == 0)
2584e1abf66STodor Tomov return MSM_VFE_VFE0_UB_SIZE_RDI;
2594e1abf66STodor Tomov else if (vfe_id == 1)
2604e1abf66STodor Tomov return MSM_VFE_VFE1_UB_SIZE_RDI;
2614e1abf66STodor Tomov
2624e1abf66STodor Tomov return 0;
2634e1abf66STodor Tomov }
2644e1abf66STodor Tomov
vfe_reg_clr(struct vfe_device * vfe,u32 reg,u32 clr_bits)2654e1abf66STodor Tomov static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
2664e1abf66STodor Tomov {
2674e1abf66STodor Tomov u32 bits = readl_relaxed(vfe->base + reg);
2684e1abf66STodor Tomov
2694e1abf66STodor Tomov writel_relaxed(bits & ~clr_bits, vfe->base + reg);
2704e1abf66STodor Tomov }
2714e1abf66STodor Tomov
vfe_reg_set(struct vfe_device * vfe,u32 reg,u32 set_bits)2724e1abf66STodor Tomov static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
2734e1abf66STodor Tomov {
2744e1abf66STodor Tomov u32 bits = readl_relaxed(vfe->base + reg);
2754e1abf66STodor Tomov
2764e1abf66STodor Tomov writel_relaxed(bits | set_bits, vfe->base + reg);
2774e1abf66STodor Tomov }
2784e1abf66STodor Tomov
vfe_global_reset(struct vfe_device * vfe)2794e1abf66STodor Tomov static void vfe_global_reset(struct vfe_device *vfe)
2804e1abf66STodor Tomov {
2814e1abf66STodor Tomov u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC |
2824e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_DSP |
2834e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_TESTGEN |
2844e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_BUS_MISR |
2854e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_PM |
2864e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_REGISTER |
2874e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_BUS_BDG |
2884e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_BUS |
2894e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_CAMIF |
2904e1abf66STodor Tomov VFE_0_GLOBAL_RESET_CMD_CORE;
2914e1abf66STodor Tomov
2924e1abf66STodor Tomov writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0);
293633b388fSRobert Foss
294633b388fSRobert Foss /* Enforce barrier between IRQ mask setup and global reset */
2954e1abf66STodor Tomov wmb();
2964e1abf66STodor Tomov writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
2974e1abf66STodor Tomov }
2984e1abf66STodor Tomov
vfe_halt_request(struct vfe_device * vfe)2994e1abf66STodor Tomov static void vfe_halt_request(struct vfe_device *vfe)
3004e1abf66STodor Tomov {
3014e1abf66STodor Tomov writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
3024e1abf66STodor Tomov vfe->base + VFE_0_BUS_BDG_CMD);
3034e1abf66STodor Tomov }
3044e1abf66STodor Tomov
vfe_halt_clear(struct vfe_device * vfe)3054e1abf66STodor Tomov static void vfe_halt_clear(struct vfe_device *vfe)
3064e1abf66STodor Tomov {
3074e1abf66STodor Tomov writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
3084e1abf66STodor Tomov }
3094e1abf66STodor Tomov
vfe_wm_enable(struct vfe_device * vfe,u8 wm,u8 enable)310633b388fSRobert Foss static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
3114e1abf66STodor Tomov {
3124e1abf66STodor Tomov if (enable)
3134e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
3144e1abf66STodor Tomov 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
3154e1abf66STodor Tomov else
3164e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),
3174e1abf66STodor Tomov 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);
3184e1abf66STodor Tomov }
3194e1abf66STodor Tomov
vfe_wm_frame_based(struct vfe_device * vfe,u8 wm,u8 enable)3204e1abf66STodor Tomov static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
3214e1abf66STodor Tomov {
3224e1abf66STodor Tomov if (enable)
3234e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
3244e1abf66STodor Tomov 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
3254e1abf66STodor Tomov else
3264e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
3274e1abf66STodor Tomov 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
3284e1abf66STodor Tomov }
3294e1abf66STodor Tomov
3304e1abf66STodor Tomov #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
3314e1abf66STodor Tomov
vfe_word_per_line_by_pixel(u32 format,u32 pixel_per_line)332312e1c85STodor Tomov static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line)
3334e1abf66STodor Tomov {
3344e1abf66STodor Tomov int val = 0;
3354e1abf66STodor Tomov
3364e1abf66STodor Tomov switch (format) {
3374e1abf66STodor Tomov case V4L2_PIX_FMT_NV12:
3384e1abf66STodor Tomov case V4L2_PIX_FMT_NV21:
3394e1abf66STodor Tomov case V4L2_PIX_FMT_NV16:
3404e1abf66STodor Tomov case V4L2_PIX_FMT_NV61:
3414e1abf66STodor Tomov val = CALC_WORD(pixel_per_line, 1, 8);
3424e1abf66STodor Tomov break;
3434e1abf66STodor Tomov case V4L2_PIX_FMT_YUYV:
3444e1abf66STodor Tomov case V4L2_PIX_FMT_YVYU:
3454e1abf66STodor Tomov case V4L2_PIX_FMT_UYVY:
3464e1abf66STodor Tomov case V4L2_PIX_FMT_VYUY:
3474e1abf66STodor Tomov val = CALC_WORD(pixel_per_line, 2, 8);
3484e1abf66STodor Tomov break;
3494e1abf66STodor Tomov }
3504e1abf66STodor Tomov
3514e1abf66STodor Tomov return val;
3524e1abf66STodor Tomov }
3534e1abf66STodor Tomov
vfe_word_per_line_by_bytes(u32 bytes_per_line)354312e1c85STodor Tomov static int vfe_word_per_line_by_bytes(u32 bytes_per_line)
355312e1c85STodor Tomov {
356312e1c85STodor Tomov return CALC_WORD(bytes_per_line, 1, 8);
357312e1c85STodor Tomov }
358312e1c85STodor Tomov
vfe_get_wm_sizes(struct v4l2_pix_format_mplane * pix,u8 plane,u16 * width,u16 * height,u16 * bytesperline)3594e1abf66STodor Tomov static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
3604e1abf66STodor Tomov u16 *width, u16 *height, u16 *bytesperline)
3614e1abf66STodor Tomov {
362749d8965STom Rix *width = pix->width;
363749d8965STom Rix *height = pix->height;
364749d8965STom Rix
3654e1abf66STodor Tomov switch (pix->pixelformat) {
3664e1abf66STodor Tomov case V4L2_PIX_FMT_NV12:
3674e1abf66STodor Tomov case V4L2_PIX_FMT_NV21:
3684e1abf66STodor Tomov *bytesperline = pix->plane_fmt[0].bytesperline;
3694e1abf66STodor Tomov if (plane == 1)
3704e1abf66STodor Tomov *height /= 2;
3714e1abf66STodor Tomov break;
3724e1abf66STodor Tomov case V4L2_PIX_FMT_NV16:
3734e1abf66STodor Tomov case V4L2_PIX_FMT_NV61:
3744e1abf66STodor Tomov *bytesperline = pix->plane_fmt[0].bytesperline;
3754e1abf66STodor Tomov break;
376312e1c85STodor Tomov case V4L2_PIX_FMT_YUYV:
377312e1c85STodor Tomov case V4L2_PIX_FMT_YVYU:
378312e1c85STodor Tomov case V4L2_PIX_FMT_VYUY:
379312e1c85STodor Tomov case V4L2_PIX_FMT_UYVY:
380312e1c85STodor Tomov *bytesperline = pix->plane_fmt[plane].bytesperline;
381312e1c85STodor Tomov break;
3824e1abf66STodor Tomov }
3834e1abf66STodor Tomov }
3844e1abf66STodor Tomov
vfe_wm_line_based(struct vfe_device * vfe,u32 wm,struct v4l2_pix_format_mplane * pix,u8 plane,u32 enable)3854e1abf66STodor Tomov static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
3864e1abf66STodor Tomov struct v4l2_pix_format_mplane *pix,
3874e1abf66STodor Tomov u8 plane, u32 enable)
3884e1abf66STodor Tomov {
3894e1abf66STodor Tomov u32 reg;
3904e1abf66STodor Tomov
3914e1abf66STodor Tomov if (enable) {
3924e1abf66STodor Tomov u16 width = 0, height = 0, bytesperline = 0, wpl;
3934e1abf66STodor Tomov
3944e1abf66STodor Tomov vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
3954e1abf66STodor Tomov
396312e1c85STodor Tomov wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width);
3974e1abf66STodor Tomov
3984e1abf66STodor Tomov reg = height - 1;
3994e1abf66STodor Tomov reg |= ((wpl + 3) / 4 - 1) << 16;
4004e1abf66STodor Tomov
4014e1abf66STodor Tomov writel_relaxed(reg, vfe->base +
4024e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
4034e1abf66STodor Tomov
404312e1c85STodor Tomov wpl = vfe_word_per_line_by_bytes(bytesperline);
4054e1abf66STodor Tomov
4064e1abf66STodor Tomov reg = 0x3;
4074e1abf66STodor Tomov reg |= (height - 1) << 2;
4084e1abf66STodor Tomov reg |= ((wpl + 1) / 2) << 16;
4094e1abf66STodor Tomov
4104e1abf66STodor Tomov writel_relaxed(reg, vfe->base +
4114e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
4124e1abf66STodor Tomov } else {
4134e1abf66STodor Tomov writel_relaxed(0, vfe->base +
4144e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
4154e1abf66STodor Tomov writel_relaxed(0, vfe->base +
4164e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
4174e1abf66STodor Tomov }
4184e1abf66STodor Tomov }
4194e1abf66STodor Tomov
vfe_wm_set_framedrop_period(struct vfe_device * vfe,u8 wm,u8 per)4204e1abf66STodor Tomov static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
4214e1abf66STodor Tomov {
4224e1abf66STodor Tomov u32 reg;
4234e1abf66STodor Tomov
4244e1abf66STodor Tomov reg = readl_relaxed(vfe->base +
4254e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
4264e1abf66STodor Tomov
4274e1abf66STodor Tomov reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
4284e1abf66STodor Tomov
4294e1abf66STodor Tomov reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
4304e1abf66STodor Tomov & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
4314e1abf66STodor Tomov
4324e1abf66STodor Tomov writel_relaxed(reg,
4334e1abf66STodor Tomov vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
4344e1abf66STodor Tomov }
4354e1abf66STodor Tomov
vfe_wm_set_framedrop_pattern(struct vfe_device * vfe,u8 wm,u32 pattern)4364e1abf66STodor Tomov static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
4374e1abf66STodor Tomov u32 pattern)
4384e1abf66STodor Tomov {
4394e1abf66STodor Tomov writel_relaxed(pattern,
4404e1abf66STodor Tomov vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
4414e1abf66STodor Tomov }
4424e1abf66STodor Tomov
vfe_wm_set_ub_cfg(struct vfe_device * vfe,u8 wm,u16 offset,u16 depth)4434e1abf66STodor Tomov static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
4444e1abf66STodor Tomov u16 offset, u16 depth)
4454e1abf66STodor Tomov {
4464e1abf66STodor Tomov u32 reg;
4474e1abf66STodor Tomov
4484e1abf66STodor Tomov reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
4494e1abf66STodor Tomov depth;
4504e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
4514e1abf66STodor Tomov }
4524e1abf66STodor Tomov
vfe_bus_reload_wm(struct vfe_device * vfe,u8 wm)4534e1abf66STodor Tomov static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
4544e1abf66STodor Tomov {
455633b388fSRobert Foss /* Enforce barrier between any outstanding register write */
4564e1abf66STodor Tomov wmb();
457633b388fSRobert Foss
4584e1abf66STodor Tomov writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
459633b388fSRobert Foss
460633b388fSRobert Foss /* Use barrier to make sure bus reload is issued before anything else */
4614e1abf66STodor Tomov wmb();
4624e1abf66STodor Tomov }
4634e1abf66STodor Tomov
vfe_wm_set_ping_addr(struct vfe_device * vfe,u8 wm,u32 addr)4644e1abf66STodor Tomov static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
4654e1abf66STodor Tomov {
4664e1abf66STodor Tomov writel_relaxed(addr,
4674e1abf66STodor Tomov vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
4684e1abf66STodor Tomov }
4694e1abf66STodor Tomov
vfe_wm_set_pong_addr(struct vfe_device * vfe,u8 wm,u32 addr)4704e1abf66STodor Tomov static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
4714e1abf66STodor Tomov {
4724e1abf66STodor Tomov writel_relaxed(addr,
4734e1abf66STodor Tomov vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
4744e1abf66STodor Tomov }
4754e1abf66STodor Tomov
vfe_wm_get_ping_pong_status(struct vfe_device * vfe,u8 wm)4764e1abf66STodor Tomov static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
4774e1abf66STodor Tomov {
4784e1abf66STodor Tomov u32 reg;
4794e1abf66STodor Tomov
4804e1abf66STodor Tomov reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
4814e1abf66STodor Tomov
4824e1abf66STodor Tomov return (reg >> wm) & 0x1;
4834e1abf66STodor Tomov }
4844e1abf66STodor Tomov
vfe_bus_enable_wr_if(struct vfe_device * vfe,u8 enable)4854e1abf66STodor Tomov static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
4864e1abf66STodor Tomov {
4874e1abf66STodor Tomov if (enable)
4884e1abf66STodor Tomov writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG);
4894e1abf66STodor Tomov else
4904e1abf66STodor Tomov writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
4914e1abf66STodor Tomov }
4924e1abf66STodor Tomov
vfe_bus_connect_wm_to_rdi(struct vfe_device * vfe,u8 wm,enum vfe_line_id id)4934e1abf66STodor Tomov static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
4944e1abf66STodor Tomov enum vfe_line_id id)
4954e1abf66STodor Tomov {
4964e1abf66STodor Tomov u32 reg;
4974e1abf66STodor Tomov
4984e1abf66STodor Tomov reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
4994e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
5004e1abf66STodor Tomov
5014e1abf66STodor Tomov reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
5024e1abf66STodor Tomov reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
5034e1abf66STodor Tomov VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
5044e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
5054e1abf66STodor Tomov
5064e1abf66STodor Tomov switch (id) {
5074e1abf66STodor Tomov case VFE_LINE_RDI0:
5084e1abf66STodor Tomov default:
5094e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
5104e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5114e1abf66STodor Tomov break;
5124e1abf66STodor Tomov case VFE_LINE_RDI1:
5134e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
5144e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5154e1abf66STodor Tomov break;
5164e1abf66STodor Tomov case VFE_LINE_RDI2:
5174e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
5184e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5194e1abf66STodor Tomov break;
5204e1abf66STodor Tomov }
5214e1abf66STodor Tomov
5224e1abf66STodor Tomov if (wm % 2 == 1)
5234e1abf66STodor Tomov reg <<= 16;
5244e1abf66STodor Tomov
5254e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
5264e1abf66STodor Tomov }
5274e1abf66STodor Tomov
vfe_wm_set_subsample(struct vfe_device * vfe,u8 wm)5284e1abf66STodor Tomov static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
5294e1abf66STodor Tomov {
5304e1abf66STodor Tomov writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
5314e1abf66STodor Tomov vfe->base +
5324e1abf66STodor Tomov VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
5334e1abf66STodor Tomov }
5344e1abf66STodor Tomov
vfe_bus_disconnect_wm_from_rdi(struct vfe_device * vfe,u8 wm,enum vfe_line_id id)5354e1abf66STodor Tomov static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
5364e1abf66STodor Tomov enum vfe_line_id id)
5374e1abf66STodor Tomov {
5384e1abf66STodor Tomov u32 reg;
5394e1abf66STodor Tomov
5404e1abf66STodor Tomov reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
5414e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
5424e1abf66STodor Tomov
5434e1abf66STodor Tomov switch (id) {
5444e1abf66STodor Tomov case VFE_LINE_RDI0:
5454e1abf66STodor Tomov default:
5464e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
5474e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5484e1abf66STodor Tomov break;
5494e1abf66STodor Tomov case VFE_LINE_RDI1:
5504e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
5514e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5524e1abf66STodor Tomov break;
5534e1abf66STodor Tomov case VFE_LINE_RDI2:
5544e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
5554e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5564e1abf66STodor Tomov break;
5574e1abf66STodor Tomov }
5584e1abf66STodor Tomov
5594e1abf66STodor Tomov if (wm % 2 == 1)
5604e1abf66STodor Tomov reg <<= 16;
5614e1abf66STodor Tomov
5624e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
5634e1abf66STodor Tomov }
5644e1abf66STodor Tomov
vfe_set_xbar_cfg(struct vfe_device * vfe,struct vfe_output * output,u8 enable)5654e1abf66STodor Tomov static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
5664e1abf66STodor Tomov u8 enable)
5674e1abf66STodor Tomov {
5684e1abf66STodor Tomov struct vfe_line *line = container_of(output, struct vfe_line, output);
5694e1abf66STodor Tomov u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
5704e1abf66STodor Tomov u32 reg;
5714e1abf66STodor Tomov
572312e1c85STodor Tomov switch (p) {
573312e1c85STodor Tomov case V4L2_PIX_FMT_NV12:
574312e1c85STodor Tomov case V4L2_PIX_FMT_NV21:
575312e1c85STodor Tomov case V4L2_PIX_FMT_NV16:
576312e1c85STodor Tomov case V4L2_PIX_FMT_NV61:
5774e1abf66STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
5784e1abf66STodor Tomov VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
5794e1abf66STodor Tomov
580312e1c85STodor Tomov if (output->wm_idx[0] % 2 == 1)
5814e1abf66STodor Tomov reg <<= 16;
5824e1abf66STodor Tomov
5834e1abf66STodor Tomov if (enable)
5844e1abf66STodor Tomov vfe_reg_set(vfe,
585312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
5864e1abf66STodor Tomov reg);
5874e1abf66STodor Tomov else
5884e1abf66STodor Tomov vfe_reg_clr(vfe,
589312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
5904e1abf66STodor Tomov reg);
591312e1c85STodor Tomov
592312e1c85STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
593312e1c85STodor Tomov if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
594312e1c85STodor Tomov reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
595312e1c85STodor Tomov
596312e1c85STodor Tomov if (output->wm_idx[1] % 2 == 1)
597312e1c85STodor Tomov reg <<= 16;
598312e1c85STodor Tomov
599312e1c85STodor Tomov if (enable)
600312e1c85STodor Tomov vfe_reg_set(vfe,
601312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
602312e1c85STodor Tomov reg);
603312e1c85STodor Tomov else
604312e1c85STodor Tomov vfe_reg_clr(vfe,
605312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
606312e1c85STodor Tomov reg);
607312e1c85STodor Tomov break;
608312e1c85STodor Tomov case V4L2_PIX_FMT_YUYV:
609312e1c85STodor Tomov case V4L2_PIX_FMT_YVYU:
610312e1c85STodor Tomov case V4L2_PIX_FMT_VYUY:
611312e1c85STodor Tomov case V4L2_PIX_FMT_UYVY:
612312e1c85STodor Tomov reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN;
613312e1c85STodor Tomov reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
614312e1c85STodor Tomov
615312e1c85STodor Tomov if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU)
616312e1c85STodor Tomov reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
617312e1c85STodor Tomov
618312e1c85STodor Tomov if (output->wm_idx[0] % 2 == 1)
619312e1c85STodor Tomov reg <<= 16;
620312e1c85STodor Tomov
621312e1c85STodor Tomov if (enable)
622312e1c85STodor Tomov vfe_reg_set(vfe,
623312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
624312e1c85STodor Tomov reg);
625312e1c85STodor Tomov else
626312e1c85STodor Tomov vfe_reg_clr(vfe,
627312e1c85STodor Tomov VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
628312e1c85STodor Tomov reg);
629312e1c85STodor Tomov break;
630312e1c85STodor Tomov default:
631312e1c85STodor Tomov break;
6324e1abf66STodor Tomov }
6334e1abf66STodor Tomov }
6344e1abf66STodor Tomov
vfe_set_realign_cfg(struct vfe_device * vfe,struct vfe_line * line,u8 enable)635312e1c85STodor Tomov static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
636312e1c85STodor Tomov u8 enable)
637312e1c85STodor Tomov {
638312e1c85STodor Tomov u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
639312e1c85STodor Tomov u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF;
640312e1c85STodor Tomov
641312e1c85STodor Tomov if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU &&
642312e1c85STodor Tomov p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY)
643312e1c85STodor Tomov return;
644312e1c85STodor Tomov
645312e1c85STodor Tomov if (enable) {
646312e1c85STodor Tomov vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val);
647312e1c85STodor Tomov } else {
648312e1c85STodor Tomov vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val);
649312e1c85STodor Tomov return;
650312e1c85STodor Tomov }
651312e1c85STodor Tomov
652312e1c85STodor Tomov val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE;
653312e1c85STodor Tomov
654312e1c85STodor Tomov if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV)
655312e1c85STodor Tomov val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL;
656312e1c85STodor Tomov else
657312e1c85STodor Tomov val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL;
658312e1c85STodor Tomov
659312e1c85STodor Tomov writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG);
660312e1c85STodor Tomov }
661312e1c85STodor Tomov
vfe_set_rdi_cid(struct vfe_device * vfe,enum vfe_line_id id,u8 cid)6624e1abf66STodor Tomov static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
6634e1abf66STodor Tomov {
6644e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
6654e1abf66STodor Tomov VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
6664e1abf66STodor Tomov
6674e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
6684e1abf66STodor Tomov cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
6694e1abf66STodor Tomov }
6704e1abf66STodor Tomov
vfe_reg_update(struct vfe_device * vfe,enum vfe_line_id line_id)6714e1abf66STodor Tomov static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
6724e1abf66STodor Tomov {
6734e1abf66STodor Tomov vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
674633b388fSRobert Foss
675633b388fSRobert Foss /* Enforce barrier between line update and commit */
6764e1abf66STodor Tomov wmb();
6774e1abf66STodor Tomov writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
678633b388fSRobert Foss
679633b388fSRobert Foss /* Make sure register update is issued before further reg writes */
6804e1abf66STodor Tomov wmb();
6814e1abf66STodor Tomov }
6824e1abf66STodor Tomov
vfe_reg_update_clear(struct vfe_device * vfe,enum vfe_line_id line_id)6834e1abf66STodor Tomov static inline void vfe_reg_update_clear(struct vfe_device *vfe,
6844e1abf66STodor Tomov enum vfe_line_id line_id)
6854e1abf66STodor Tomov {
6864e1abf66STodor Tomov vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
6874e1abf66STodor Tomov }
6884e1abf66STodor Tomov
vfe_enable_irq_wm_line(struct vfe_device * vfe,u8 wm,enum vfe_line_id line_id,u8 enable)6894e1abf66STodor Tomov static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
6904e1abf66STodor Tomov enum vfe_line_id line_id, u8 enable)
6914e1abf66STodor Tomov {
6924e1abf66STodor Tomov u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
6934e1abf66STodor Tomov VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
6944e1abf66STodor Tomov u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
6954e1abf66STodor Tomov VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
6964e1abf66STodor Tomov
6974e1abf66STodor Tomov if (enable) {
6984e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
6994e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
7004e1abf66STodor Tomov } else {
7014e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
7024e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
7034e1abf66STodor Tomov }
7044e1abf66STodor Tomov }
7054e1abf66STodor Tomov
vfe_enable_irq_pix_line(struct vfe_device * vfe,u8 comp,enum vfe_line_id line_id,u8 enable)7064e1abf66STodor Tomov static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
7074e1abf66STodor Tomov enum vfe_line_id line_id, u8 enable)
7084e1abf66STodor Tomov {
7094e1abf66STodor Tomov struct vfe_output *output = &vfe->line[line_id].output;
7104e1abf66STodor Tomov unsigned int i;
7114e1abf66STodor Tomov u32 irq_en0;
7124e1abf66STodor Tomov u32 irq_en1;
7134e1abf66STodor Tomov u32 comp_mask = 0;
7144e1abf66STodor Tomov
7154e1abf66STodor Tomov irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
7164e1abf66STodor Tomov irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
7174e1abf66STodor Tomov irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
7184e1abf66STodor Tomov irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
7194e1abf66STodor Tomov irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
7204e1abf66STodor Tomov for (i = 0; i < output->wm_num; i++) {
7214e1abf66STodor Tomov irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(
7224e1abf66STodor Tomov output->wm_idx[i]);
7234e1abf66STodor Tomov comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
7244e1abf66STodor Tomov }
7254e1abf66STodor Tomov
7264e1abf66STodor Tomov if (enable) {
7274e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
7284e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
7294e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
7304e1abf66STodor Tomov } else {
7314e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
7324e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
7334e1abf66STodor Tomov vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
7344e1abf66STodor Tomov }
7354e1abf66STodor Tomov }
7364e1abf66STodor Tomov
vfe_enable_irq_common(struct vfe_device * vfe)7374e1abf66STodor Tomov static void vfe_enable_irq_common(struct vfe_device *vfe)
7384e1abf66STodor Tomov {
7394e1abf66STodor Tomov u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
7404e1abf66STodor Tomov u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
7414e1abf66STodor Tomov VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
7424e1abf66STodor Tomov
7434e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
7444e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
7454e1abf66STodor Tomov }
7464e1abf66STodor Tomov
vfe_set_demux_cfg(struct vfe_device * vfe,struct vfe_line * line)7474e1abf66STodor Tomov static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
7484e1abf66STodor Tomov {
7494e1abf66STodor Tomov u32 val, even_cfg, odd_cfg;
7504e1abf66STodor Tomov
7514e1abf66STodor Tomov writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
7524e1abf66STodor Tomov
7534e1abf66STodor Tomov val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
7544e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
7554e1abf66STodor Tomov
7564e1abf66STodor Tomov val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
7574e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
7584e1abf66STodor Tomov
7594e1abf66STodor Tomov switch (line->fmt[MSM_VFE_PAD_SINK].code) {
76089936bfbSMartin Dørum case MEDIA_BUS_FMT_YUYV8_1X16:
7614e1abf66STodor Tomov even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
7624e1abf66STodor Tomov odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
7634e1abf66STodor Tomov break;
76489936bfbSMartin Dørum case MEDIA_BUS_FMT_YVYU8_1X16:
7654e1abf66STodor Tomov even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
7664e1abf66STodor Tomov odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
7674e1abf66STodor Tomov break;
76889936bfbSMartin Dørum case MEDIA_BUS_FMT_UYVY8_1X16:
7694e1abf66STodor Tomov default:
7704e1abf66STodor Tomov even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
7714e1abf66STodor Tomov odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
7724e1abf66STodor Tomov break;
77389936bfbSMartin Dørum case MEDIA_BUS_FMT_VYUY8_1X16:
7744e1abf66STodor Tomov even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
7754e1abf66STodor Tomov odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
7764e1abf66STodor Tomov break;
7774e1abf66STodor Tomov }
7784e1abf66STodor Tomov
7794e1abf66STodor Tomov writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
7804e1abf66STodor Tomov writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
7814e1abf66STodor Tomov }
7824e1abf66STodor Tomov
vfe_set_scale_cfg(struct vfe_device * vfe,struct vfe_line * line)7834e1abf66STodor Tomov static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
7844e1abf66STodor Tomov {
7854e1abf66STodor Tomov u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
7864e1abf66STodor Tomov u32 reg;
7874e1abf66STodor Tomov u16 input, output;
7884e1abf66STodor Tomov u8 interp_reso;
7894e1abf66STodor Tomov u32 phase_mult;
7904e1abf66STodor Tomov
7914e1abf66STodor Tomov writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
7924e1abf66STodor Tomov
7934e1abf66STodor Tomov input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
7944e1abf66STodor Tomov output = line->compose.width - 1;
7954e1abf66STodor Tomov reg = (output << 16) | input;
7964e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
7974e1abf66STodor Tomov
7984e1abf66STodor Tomov interp_reso = vfe_calc_interp_reso(input, output);
7994e1abf66STodor Tomov phase_mult = input * (1 << (14 + interp_reso)) / output;
8004e1abf66STodor Tomov reg = (interp_reso << 28) | phase_mult;
8014e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
8024e1abf66STodor Tomov
8034e1abf66STodor Tomov input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
8044e1abf66STodor Tomov output = line->compose.height - 1;
8054e1abf66STodor Tomov reg = (output << 16) | input;
8064e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
8074e1abf66STodor Tomov
8084e1abf66STodor Tomov interp_reso = vfe_calc_interp_reso(input, output);
8094e1abf66STodor Tomov phase_mult = input * (1 << (14 + interp_reso)) / output;
8104e1abf66STodor Tomov reg = (interp_reso << 28) | phase_mult;
8114e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
8124e1abf66STodor Tomov
8134e1abf66STodor Tomov writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
8144e1abf66STodor Tomov
8154e1abf66STodor Tomov input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
8164e1abf66STodor Tomov output = line->compose.width / 2 - 1;
8174e1abf66STodor Tomov reg = (output << 16) | input;
8184e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
8194e1abf66STodor Tomov
8204e1abf66STodor Tomov interp_reso = vfe_calc_interp_reso(input, output);
8214e1abf66STodor Tomov phase_mult = input * (1 << (14 + interp_reso)) / output;
8224e1abf66STodor Tomov reg = (interp_reso << 28) | phase_mult;
8234e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
8244e1abf66STodor Tomov
8254e1abf66STodor Tomov input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
8264e1abf66STodor Tomov output = line->compose.height - 1;
8274e1abf66STodor Tomov if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
8284e1abf66STodor Tomov output = line->compose.height / 2 - 1;
8294e1abf66STodor Tomov reg = (output << 16) | input;
8304e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
8314e1abf66STodor Tomov
8324e1abf66STodor Tomov interp_reso = vfe_calc_interp_reso(input, output);
8334e1abf66STodor Tomov phase_mult = input * (1 << (14 + interp_reso)) / output;
8344e1abf66STodor Tomov reg = (interp_reso << 28) | phase_mult;
8354e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
8364e1abf66STodor Tomov }
8374e1abf66STodor Tomov
vfe_set_crop_cfg(struct vfe_device * vfe,struct vfe_line * line)8384e1abf66STodor Tomov static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
8394e1abf66STodor Tomov {
8404e1abf66STodor Tomov u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
8414e1abf66STodor Tomov u32 reg;
8424e1abf66STodor Tomov u16 first, last;
8434e1abf66STodor Tomov
8444e1abf66STodor Tomov first = line->crop.left;
8454e1abf66STodor Tomov last = line->crop.left + line->crop.width - 1;
8464e1abf66STodor Tomov reg = (first << 16) | last;
8474e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
8484e1abf66STodor Tomov
8494e1abf66STodor Tomov first = line->crop.top;
8504e1abf66STodor Tomov last = line->crop.top + line->crop.height - 1;
8514e1abf66STodor Tomov reg = (first << 16) | last;
8524e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
8534e1abf66STodor Tomov
8544e1abf66STodor Tomov first = line->crop.left / 2;
8554e1abf66STodor Tomov last = line->crop.left / 2 + line->crop.width / 2 - 1;
8564e1abf66STodor Tomov reg = (first << 16) | last;
8574e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
8584e1abf66STodor Tomov
8594e1abf66STodor Tomov first = line->crop.top;
8604e1abf66STodor Tomov last = line->crop.top + line->crop.height - 1;
8614e1abf66STodor Tomov if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
8624e1abf66STodor Tomov first = line->crop.top / 2;
8634e1abf66STodor Tomov last = line->crop.top / 2 + line->crop.height / 2 - 1;
8644e1abf66STodor Tomov }
8654e1abf66STodor Tomov reg = (first << 16) | last;
8664e1abf66STodor Tomov writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
8674e1abf66STodor Tomov }
8684e1abf66STodor Tomov
vfe_set_clamp_cfg(struct vfe_device * vfe)8694e1abf66STodor Tomov static void vfe_set_clamp_cfg(struct vfe_device *vfe)
8704e1abf66STodor Tomov {
8714e1abf66STodor Tomov u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
8724e1abf66STodor Tomov VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
8734e1abf66STodor Tomov VFE_0_CLAMP_ENC_MAX_CFG_CH2;
8744e1abf66STodor Tomov
8754e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
8764e1abf66STodor Tomov
8774e1abf66STodor Tomov val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
8784e1abf66STodor Tomov VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
8794e1abf66STodor Tomov VFE_0_CLAMP_ENC_MIN_CFG_CH2;
8804e1abf66STodor Tomov
8814e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
8824e1abf66STodor Tomov }
8834e1abf66STodor Tomov
vfe_set_qos(struct vfe_device * vfe)884633b388fSRobert Foss static void vfe_set_qos(struct vfe_device *vfe)
8854e1abf66STodor Tomov {
8864e1abf66STodor Tomov u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
8874e1abf66STodor Tomov u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
8884e1abf66STodor Tomov
8894e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
8904e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
8914e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
8924e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
8934e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
8944e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
8954e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
8964e1abf66STodor Tomov writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
8974e1abf66STodor Tomov }
8984e1abf66STodor Tomov
vfe_set_ds(struct vfe_device * vfe)899633b388fSRobert Foss static void vfe_set_ds(struct vfe_device *vfe)
9004e1abf66STodor Tomov {
9014e1abf66STodor Tomov u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;
9024e1abf66STodor Tomov u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;
9034e1abf66STodor Tomov
9044e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);
9054e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);
9064e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);
9074e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);
9084e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);
9094e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);
9104e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);
9114e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);
9124e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);
9134e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);
9144e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);
9154e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);
9164e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);
9174e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);
9184e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);
9194e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);
9204e1abf66STodor Tomov writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
9214e1abf66STodor Tomov }
9224e1abf66STodor Tomov
vfe_set_cgc_override(struct vfe_device * vfe,u8 wm,u8 enable)9234e1abf66STodor Tomov static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
9244e1abf66STodor Tomov {
9254e1abf66STodor Tomov /* empty */
9264e1abf66STodor Tomov }
9274e1abf66STodor Tomov
vfe_set_camif_cfg(struct vfe_device * vfe,struct vfe_line * line)9284e1abf66STodor Tomov static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
9294e1abf66STodor Tomov {
9304e1abf66STodor Tomov u32 val;
9314e1abf66STodor Tomov
9324e1abf66STodor Tomov switch (line->fmt[MSM_VFE_PAD_SINK].code) {
93389936bfbSMartin Dørum case MEDIA_BUS_FMT_YUYV8_1X16:
9344e1abf66STodor Tomov val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
9354e1abf66STodor Tomov break;
93689936bfbSMartin Dørum case MEDIA_BUS_FMT_YVYU8_1X16:
9374e1abf66STodor Tomov val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
9384e1abf66STodor Tomov break;
93989936bfbSMartin Dørum case MEDIA_BUS_FMT_UYVY8_1X16:
9404e1abf66STodor Tomov default:
9414e1abf66STodor Tomov val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
9424e1abf66STodor Tomov break;
94389936bfbSMartin Dørum case MEDIA_BUS_FMT_VYUY8_1X16:
9444e1abf66STodor Tomov val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
9454e1abf66STodor Tomov break;
9464e1abf66STodor Tomov }
9474e1abf66STodor Tomov
9484e1abf66STodor Tomov val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN;
9494e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
9504e1abf66STodor Tomov
9514e1abf66STodor Tomov val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
9524e1abf66STodor Tomov val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16;
9534e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
9544e1abf66STodor Tomov
9554e1abf66STodor Tomov val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
9564e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
9574e1abf66STodor Tomov
9584e1abf66STodor Tomov val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
9594e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
9604e1abf66STodor Tomov
9614e1abf66STodor Tomov val = 0xffffffff;
9624e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG);
9634e1abf66STodor Tomov
9644e1abf66STodor Tomov val = 0xffffffff;
9654e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN);
9664e1abf66STodor Tomov
9674e1abf66STodor Tomov val = 0xffffffff;
9684e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
9694e1abf66STodor Tomov
9704e1abf66STodor Tomov val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
9714e1abf66STodor Tomov vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
9724e1abf66STodor Tomov
9734e1abf66STodor Tomov val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
9744e1abf66STodor Tomov writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
9754e1abf66STodor Tomov }
9764e1abf66STodor Tomov
vfe_set_camif_cmd(struct vfe_device * vfe,u8 enable)9774e1abf66STodor Tomov static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
9784e1abf66STodor Tomov {
9794e1abf66STodor Tomov u32 cmd;
9804e1abf66STodor Tomov
9814e1abf66STodor Tomov cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
9824e1abf66STodor Tomov writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
983633b388fSRobert Foss
984633b388fSRobert Foss /* Make sure camif command is issued written before it is changed again */
9854e1abf66STodor Tomov wmb();
9864e1abf66STodor Tomov
9874e1abf66STodor Tomov if (enable)
9884e1abf66STodor Tomov cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
9894e1abf66STodor Tomov else
9904e1abf66STodor Tomov cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
9914e1abf66STodor Tomov
9924e1abf66STodor Tomov writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
9934e1abf66STodor Tomov }
9944e1abf66STodor Tomov
vfe_set_module_cfg(struct vfe_device * vfe,u8 enable)9954e1abf66STodor Tomov static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
9964e1abf66STodor Tomov {
9974e1abf66STodor Tomov u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX |
9984e1abf66STodor Tomov VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE;
9994e1abf66STodor Tomov u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC |
10004e1abf66STodor Tomov VFE_0_MODULE_ZOOM_EN_CROP_ENC;
10014e1abf66STodor Tomov
10024e1abf66STodor Tomov if (enable) {
1003312e1c85STodor Tomov vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens);
1004312e1c85STodor Tomov vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
10054e1abf66STodor Tomov } else {
1006312e1c85STodor Tomov vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens);
1007312e1c85STodor Tomov vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
10084e1abf66STodor Tomov }
10094e1abf66STodor Tomov }
10104e1abf66STodor Tomov
vfe_camif_wait_for_stop(struct vfe_device * vfe,struct device * dev)10114e1abf66STodor Tomov static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
10124e1abf66STodor Tomov {
10134e1abf66STodor Tomov u32 val;
10144e1abf66STodor Tomov int ret;
10154e1abf66STodor Tomov
10164e1abf66STodor Tomov ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
10174e1abf66STodor Tomov val,
10184e1abf66STodor Tomov (val & VFE_0_CAMIF_STATUS_HALT),
10194e1abf66STodor Tomov CAMIF_TIMEOUT_SLEEP_US,
10204e1abf66STodor Tomov CAMIF_TIMEOUT_ALL_US);
10214e1abf66STodor Tomov if (ret < 0)
10224e1abf66STodor Tomov dev_err(dev, "%s: camif stop timeout\n", __func__);
10234e1abf66STodor Tomov
10244e1abf66STodor Tomov return ret;
10254e1abf66STodor Tomov }
10264e1abf66STodor Tomov
10274e1abf66STodor Tomov
10284e1abf66STodor Tomov
10294e1abf66STodor Tomov /*
1030ad46e1a8SRobert Foss * vfe_isr - VFE module interrupt handler
10314e1abf66STodor Tomov * @irq: Interrupt line
10324e1abf66STodor Tomov * @dev: VFE device
10334e1abf66STodor Tomov *
10344e1abf66STodor Tomov * Return IRQ_HANDLED on success
10354e1abf66STodor Tomov */
vfe_isr(int irq,void * dev)10364e1abf66STodor Tomov static irqreturn_t vfe_isr(int irq, void *dev)
10374e1abf66STodor Tomov {
10384e1abf66STodor Tomov struct vfe_device *vfe = dev;
10394e1abf66STodor Tomov u32 value0, value1;
10404e1abf66STodor Tomov int i, j;
10414e1abf66STodor Tomov
1042ae44829aSRadoslav Tsvetkov vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
10434e1abf66STodor Tomov
1044c3177cb0SRobert Foss dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
10454e1abf66STodor Tomov value0, value1);
10464e1abf66STodor Tomov
10474e1abf66STodor Tomov if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
10484e1abf66STodor Tomov vfe->isr_ops.reset_ack(vfe);
10494e1abf66STodor Tomov
10504e1abf66STodor Tomov if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
1051ae44829aSRadoslav Tsvetkov vfe->res->hw_ops->violation_read(vfe);
10524e1abf66STodor Tomov
10534e1abf66STodor Tomov if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
10544e1abf66STodor Tomov vfe->isr_ops.halt_ack(vfe);
10554e1abf66STodor Tomov
1056ae44829aSRadoslav Tsvetkov for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
10574e1abf66STodor Tomov if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
10584e1abf66STodor Tomov vfe->isr_ops.reg_update(vfe, i);
10594e1abf66STodor Tomov
10604e1abf66STodor Tomov if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
10614e1abf66STodor Tomov vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
10624e1abf66STodor Tomov
10634e1abf66STodor Tomov for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
10644e1abf66STodor Tomov if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
10654e1abf66STodor Tomov vfe->isr_ops.sof(vfe, i);
10664e1abf66STodor Tomov
10674e1abf66STodor Tomov for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
10684e1abf66STodor Tomov if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
10694e1abf66STodor Tomov vfe->isr_ops.comp_done(vfe, i);
10704e1abf66STodor Tomov for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
10714e1abf66STodor Tomov if (vfe->wm_output_map[j] == VFE_LINE_PIX)
10724e1abf66STodor Tomov value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
10734e1abf66STodor Tomov }
10744e1abf66STodor Tomov
10754e1abf66STodor Tomov for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
10764e1abf66STodor Tomov if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
10774e1abf66STodor Tomov vfe->isr_ops.wm_done(vfe, i);
10784e1abf66STodor Tomov
10794e1abf66STodor Tomov return IRQ_HANDLED;
10804e1abf66STodor Tomov }
10814e1abf66STodor Tomov
vfe_isr_read(struct vfe_device * vfe,u32 * value0,u32 * value1)1082633b388fSRobert Foss static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
1083633b388fSRobert Foss {
1084633b388fSRobert Foss *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
1085633b388fSRobert Foss *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
1086633b388fSRobert Foss
1087633b388fSRobert Foss writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
1088633b388fSRobert Foss writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
1089633b388fSRobert Foss
1090633b388fSRobert Foss /* Enforce barrier between local & global IRQ clear */
1091633b388fSRobert Foss wmb();
1092633b388fSRobert Foss writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1093633b388fSRobert Foss }
1094633b388fSRobert Foss
vfe_violation_read(struct vfe_device * vfe)1095633b388fSRobert Foss static void vfe_violation_read(struct vfe_device *vfe)
1096633b388fSRobert Foss {
1097633b388fSRobert Foss u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
1098633b388fSRobert Foss
1099633b388fSRobert Foss pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
1100633b388fSRobert Foss }
1101633b388fSRobert Foss
1102633b388fSRobert Foss static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {
11034e1abf66STodor Tomov .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
11044e1abf66STodor Tomov .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
1105633b388fSRobert Foss .bus_enable_wr_if = vfe_bus_enable_wr_if,
1106633b388fSRobert Foss .bus_reload_wm = vfe_bus_reload_wm,
1107633b388fSRobert Foss .camif_wait_for_stop = vfe_camif_wait_for_stop,
11084e1abf66STodor Tomov .enable_irq_common = vfe_enable_irq_common,
1109633b388fSRobert Foss .enable_irq_pix_line = vfe_enable_irq_pix_line,
1110633b388fSRobert Foss .enable_irq_wm_line = vfe_enable_irq_wm_line,
1111633b388fSRobert Foss .get_ub_size = vfe_get_ub_size,
1112633b388fSRobert Foss .halt_clear = vfe_halt_clear,
1113633b388fSRobert Foss .halt_request = vfe_halt_request,
11144e1abf66STodor Tomov .set_camif_cfg = vfe_set_camif_cfg,
11154e1abf66STodor Tomov .set_camif_cmd = vfe_set_camif_cmd,
1116633b388fSRobert Foss .set_cgc_override = vfe_set_cgc_override,
1117633b388fSRobert Foss .set_clamp_cfg = vfe_set_clamp_cfg,
1118633b388fSRobert Foss .set_crop_cfg = vfe_set_crop_cfg,
1119633b388fSRobert Foss .set_demux_cfg = vfe_set_demux_cfg,
1120633b388fSRobert Foss .set_ds = vfe_set_ds,
11214e1abf66STodor Tomov .set_module_cfg = vfe_set_module_cfg,
1122633b388fSRobert Foss .set_qos = vfe_set_qos,
1123633b388fSRobert Foss .set_rdi_cid = vfe_set_rdi_cid,
1124633b388fSRobert Foss .set_realign_cfg = vfe_set_realign_cfg,
1125633b388fSRobert Foss .set_scale_cfg = vfe_set_scale_cfg,
1126633b388fSRobert Foss .set_xbar_cfg = vfe_set_xbar_cfg,
1127633b388fSRobert Foss .wm_enable = vfe_wm_enable,
1128633b388fSRobert Foss .wm_frame_based = vfe_wm_frame_based,
1129633b388fSRobert Foss .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
1130633b388fSRobert Foss .wm_line_based = vfe_wm_line_based,
1131633b388fSRobert Foss .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
1132633b388fSRobert Foss .wm_set_framedrop_period = vfe_wm_set_framedrop_period,
1133633b388fSRobert Foss .wm_set_ping_addr = vfe_wm_set_ping_addr,
1134633b388fSRobert Foss .wm_set_pong_addr = vfe_wm_set_pong_addr,
1135633b388fSRobert Foss .wm_set_subsample = vfe_wm_set_subsample,
1136633b388fSRobert Foss .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
11374e1abf66STodor Tomov };
113840296e71SAngeloGioacchino Del Regno
vfe_subdev_init(struct device * dev,struct vfe_device * vfe)1139633b388fSRobert Foss static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
114040296e71SAngeloGioacchino Del Regno {
1141633b388fSRobert Foss vfe->isr_ops = vfe_isr_ops_gen1;
1142633b388fSRobert Foss vfe->ops_gen1 = &vfe_ops_gen1_4_7;
1143633b388fSRobert Foss vfe->video_ops = vfe_video_ops_gen1;
114440296e71SAngeloGioacchino Del Regno }
114540296e71SAngeloGioacchino Del Regno
1146633b388fSRobert Foss const struct vfe_hw_ops vfe_ops_4_7 = {
114740296e71SAngeloGioacchino Del Regno .global_reset = vfe_global_reset,
1148d2e86540SRobert Foss .hw_version = vfe_hw_version,
114940296e71SAngeloGioacchino Del Regno .isr_read = vfe_isr_read,
115040296e71SAngeloGioacchino Del Regno .isr = vfe_isr,
11512f6f8af6SRobert Foss .pm_domain_off = vfe_pm_domain_off,
11522f6f8af6SRobert Foss .pm_domain_on = vfe_pm_domain_on,
1153633b388fSRobert Foss .reg_update_clear = vfe_reg_update_clear,
1154633b388fSRobert Foss .reg_update = vfe_reg_update,
1155633b388fSRobert Foss .subdev_init = vfe_subdev_init,
1156633b388fSRobert Foss .vfe_disable = vfe_gen1_disable,
1157633b388fSRobert Foss .vfe_enable = vfe_gen1_enable,
1158633b388fSRobert Foss .vfe_halt = vfe_gen1_halt,
1159633b388fSRobert Foss .violation_read = vfe_violation_read,
116040296e71SAngeloGioacchino Del Regno };
1161