1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * camss-vfe-4-8.c 4 * 5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8 6 * 7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. 8 * Copyright (C) 2015-2021 Linaro Ltd. 9 */ 10 11 #include <linux/device.h> 12 #include <linux/interrupt.h> 13 #include <linux/io.h> 14 #include <linux/iopoll.h> 15 16 #include "camss.h" 17 #include "camss-vfe.h" 18 #include "camss-vfe-gen1.h" 19 20 #define VFE_0_GLOBAL_RESET_CMD 0x018 21 #define VFE_0_GLOBAL_RESET_CMD_CORE BIT(0) 22 #define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1) 23 #define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2) 24 #define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3) 25 #define VFE_0_GLOBAL_RESET_CMD_REGISTER BIT(4) 26 #define VFE_0_GLOBAL_RESET_CMD_PM BIT(5) 27 #define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(6) 28 #define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(7) 29 #define VFE_0_GLOBAL_RESET_CMD_DSP BIT(8) 30 #define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC BIT(9) 31 32 #define VFE_0_MODULE_LENS_EN 0x040 33 #define VFE_0_MODULE_LENS_EN_DEMUX BIT(2) 34 #define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE BIT(3) 35 36 #define VFE_0_MODULE_ZOOM_EN 0x04c 37 #define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1) 38 #define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2) 39 #define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF BIT(9) 40 41 #define VFE_0_CORE_CFG 0x050 42 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4 43 #define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5 44 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6 45 #define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7 46 #define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN BIT(4) 47 48 #define VFE_0_IRQ_CMD 0x058 49 #define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0) 50 51 #define VFE_0_IRQ_MASK_0 0x05c 52 #define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0) 53 #define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1) 54 #define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) BIT((n) + 5) 55 #define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \ 56 ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)) 57 #define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) 58 #define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) 59 #define VFE_0_IRQ_MASK_0_RESET_ACK BIT(31) 60 #define VFE_0_IRQ_MASK_1 0x060 61 #define VFE_0_IRQ_MASK_1_CAMIF_ERROR BIT(0) 62 #define VFE_0_IRQ_MASK_1_VIOLATION BIT(7) 63 #define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK BIT(8) 64 #define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9) 65 #define VFE_0_IRQ_MASK_1_RDIn_SOF(n) BIT((n) + 29) 66 67 #define VFE_0_IRQ_CLEAR_0 0x064 68 #define VFE_0_IRQ_CLEAR_1 0x068 69 70 #define VFE_0_IRQ_STATUS_0 0x06c 71 #define VFE_0_IRQ_STATUS_0_CAMIF_SOF BIT(0) 72 #define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5) 73 #define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \ 74 ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)) 75 #define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) 76 #define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) 77 #define VFE_0_IRQ_STATUS_0_RESET_ACK BIT(31) 78 #define VFE_0_IRQ_STATUS_1 0x070 79 #define VFE_0_IRQ_STATUS_1_VIOLATION BIT(7) 80 #define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK BIT(8) 81 #define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) BIT((n) + 29) 82 83 #define VFE_0_IRQ_COMPOSITE_MASK_0 0x074 84 #define VFE_0_VIOLATION_STATUS 0x07c 85 86 #define VFE_0_BUS_CMD 0x80 87 #define VFE_0_BUS_CMD_Mx_RLD_CMD(x) BIT(x) 88 89 #define VFE_0_BUS_CFG 0x084 90 91 #define VFE_0_BUS_XBAR_CFG_x(x) (0x90 + 0x4 * ((x) / 2)) 92 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(2) 93 #define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN BIT(3) 94 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA (0x1 << 4) 95 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER (0x2 << 4) 96 #define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4) 97 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 98 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0x0 99 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 0xc 100 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 0xd 101 #define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 0xe 102 103 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x0a0 + 0x2c * (n)) 104 #define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0 105 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x0a4 + 0x2c * (n)) 106 #define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x0ac + 0x2c * (n)) 107 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x0b4 + 0x2c * (n)) 108 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT 1 109 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2 110 #define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1f << 2) 111 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x0b8 + 0x2c * (n)) 112 #define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16 113 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x0bc + 0x2c * (n)) 114 #define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x0c0 + 0x2c * (n)) 115 #define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \ 116 (0x0c4 + 0x2c * (n)) 117 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \ 118 (0x0c8 + 0x2c * (n)) 119 #define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff 120 121 #define VFE_0_BUS_PING_PONG_STATUS 0x338 122 123 #define VFE_0_BUS_BDG_CMD 0x400 124 #define VFE_0_BUS_BDG_CMD_HALT_REQ 1 125 126 #define VFE_0_BUS_BDG_QOS_CFG_0 0x404 127 #define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 128 #define VFE_0_BUS_BDG_QOS_CFG_1 0x408 129 #define VFE_0_BUS_BDG_QOS_CFG_2 0x40c 130 #define VFE_0_BUS_BDG_QOS_CFG_3 0x410 131 #define VFE_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5 132 #define VFE_0_BUS_BDG_QOS_CFG_4 0x414 133 #define VFE_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55 134 #define VFE_0_BUS_BDG_QOS_CFG_5 0x418 135 #define VFE_0_BUS_BDG_QOS_CFG_6 0x41c 136 #define VFE_0_BUS_BDG_QOS_CFG_7 0x420 137 #define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55 138 139 #define VFE_0_BUS_BDG_DS_CFG_0 0x424 140 #define VFE_0_BUS_BDG_DS_CFG_0_CFG 0xcccc1111 141 #define VFE_0_BUS_BDG_DS_CFG_1 0x428 142 #define VFE_0_BUS_BDG_DS_CFG_2 0x42c 143 #define VFE_0_BUS_BDG_DS_CFG_3 0x430 144 #define VFE_0_BUS_BDG_DS_CFG_4 0x434 145 #define VFE_0_BUS_BDG_DS_CFG_5 0x438 146 #define VFE_0_BUS_BDG_DS_CFG_6 0x43c 147 #define VFE_0_BUS_BDG_DS_CFG_7 0x440 148 #define VFE_0_BUS_BDG_DS_CFG_8 0x444 149 #define VFE_0_BUS_BDG_DS_CFG_9 0x448 150 #define VFE_0_BUS_BDG_DS_CFG_10 0x44c 151 #define VFE_0_BUS_BDG_DS_CFG_11 0x450 152 #define VFE_0_BUS_BDG_DS_CFG_12 0x454 153 #define VFE_0_BUS_BDG_DS_CFG_13 0x458 154 #define VFE_0_BUS_BDG_DS_CFG_14 0x45c 155 #define VFE_0_BUS_BDG_DS_CFG_15 0x460 156 #define VFE_0_BUS_BDG_DS_CFG_16 0x464 157 #define VFE_0_BUS_BDG_DS_CFG_16_CFG 0x00000110 158 159 #define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x))) 160 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 161 #define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28) 162 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4 163 #define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4) 164 #define VFE_0_RDI_CFG_x_RDI_EN_BIT BIT(2) 165 #define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3 166 167 #define VFE_0_CAMIF_CMD 0x478 168 #define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0 169 #define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1 170 #define VFE_0_CAMIF_CMD_NO_CHANGE 3 171 #define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS BIT(2) 172 #define VFE_0_CAMIF_CFG 0x47c 173 #define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN BIT(6) 174 #define VFE_0_CAMIF_FRAME_CFG 0x484 175 #define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488 176 #define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c 177 #define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490 178 #define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498 179 #define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c 180 #define VFE_0_CAMIF_STATUS 0x4a4 181 #define VFE_0_CAMIF_STATUS_HALT BIT(31) 182 183 #define VFE_0_REG_UPDATE 0x4ac 184 #define VFE_0_REG_UPDATE_RDIn(n) BIT(1 + (n)) 185 #define VFE_0_REG_UPDATE_line_n(n) \ 186 ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n)) 187 188 #define VFE_0_DEMUX_CFG 0x560 189 #define VFE_0_DEMUX_CFG_PERIOD 0x3 190 #define VFE_0_DEMUX_GAIN_0 0x564 191 #define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0) 192 #define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16) 193 #define VFE_0_DEMUX_GAIN_1 0x568 194 #define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0) 195 #define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16) 196 #define VFE_0_DEMUX_EVEN_CFG 0x574 197 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac 198 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c 199 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca 200 #define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9 201 #define VFE_0_DEMUX_ODD_CFG 0x578 202 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac 203 #define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c 204 #define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca 205 #define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9 206 207 #define VFE_0_SCALE_ENC_Y_CFG 0x91c 208 #define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x920 209 #define VFE_0_SCALE_ENC_Y_H_PHASE 0x924 210 #define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x934 211 #define VFE_0_SCALE_ENC_Y_V_PHASE 0x938 212 #define VFE_0_SCALE_ENC_CBCR_CFG 0x948 213 #define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x94c 214 #define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x950 215 #define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x960 216 #define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x964 217 218 #define VFE_0_CROP_ENC_Y_WIDTH 0x974 219 #define VFE_0_CROP_ENC_Y_HEIGHT 0x978 220 #define VFE_0_CROP_ENC_CBCR_WIDTH 0x97c 221 #define VFE_0_CROP_ENC_CBCR_HEIGHT 0x980 222 223 #define VFE_0_CLAMP_ENC_MAX_CFG 0x984 224 #define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) 225 #define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8) 226 #define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16) 227 #define VFE_0_CLAMP_ENC_MIN_CFG 0x988 228 #define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0) 229 #define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8) 230 #define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16) 231 232 #define VFE_0_REALIGN_BUF_CFG 0xaac 233 #define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL BIT(2) 234 #define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) 235 #define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) 236 237 #define VFE_0_BUS_IMAGE_MASTER_CMD 0xcec 238 #define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x) (2 * (x)) 239 240 #define CAMIF_TIMEOUT_SLEEP_US 1000 241 #define CAMIF_TIMEOUT_ALL_US 1000000 242 243 #define MSM_VFE_VFE0_UB_SIZE 2047 244 #define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3) 245 #define MSM_VFE_VFE1_UB_SIZE 1535 246 #define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3) 247 248 static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) 249 { 250 u32 bits = readl_relaxed(vfe->base + reg); 251 252 writel_relaxed(bits & ~clr_bits, vfe->base + reg); 253 } 254 255 static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits) 256 { 257 u32 bits = readl_relaxed(vfe->base + reg); 258 259 writel_relaxed(bits | set_bits, vfe->base + reg); 260 } 261 262 static void vfe_global_reset(struct vfe_device *vfe) 263 { 264 u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC | 265 VFE_0_GLOBAL_RESET_CMD_DSP | 266 VFE_0_GLOBAL_RESET_CMD_TESTGEN | 267 VFE_0_GLOBAL_RESET_CMD_BUS_MISR | 268 VFE_0_GLOBAL_RESET_CMD_PM | 269 VFE_0_GLOBAL_RESET_CMD_REGISTER | 270 VFE_0_GLOBAL_RESET_CMD_BUS_BDG | 271 VFE_0_GLOBAL_RESET_CMD_BUS | 272 VFE_0_GLOBAL_RESET_CMD_CAMIF | 273 VFE_0_GLOBAL_RESET_CMD_CORE; 274 275 writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0); 276 277 /* Enforce barrier between IRQ mask setup and global reset */ 278 wmb(); 279 writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); 280 } 281 282 static void vfe_halt_request(struct vfe_device *vfe) 283 { 284 writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ, 285 vfe->base + VFE_0_BUS_BDG_CMD); 286 } 287 288 static void vfe_halt_clear(struct vfe_device *vfe) 289 { 290 writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); 291 } 292 293 static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) 294 { 295 if (enable) 296 vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), 297 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); 298 else 299 vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), 300 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); 301 } 302 303 #define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) 304 305 static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line) 306 { 307 int val = 0; 308 309 switch (format) { 310 case V4L2_PIX_FMT_NV12: 311 case V4L2_PIX_FMT_NV21: 312 case V4L2_PIX_FMT_NV16: 313 case V4L2_PIX_FMT_NV61: 314 val = CALC_WORD(pixel_per_line, 1, 8); 315 break; 316 case V4L2_PIX_FMT_YUYV: 317 case V4L2_PIX_FMT_YVYU: 318 case V4L2_PIX_FMT_UYVY: 319 case V4L2_PIX_FMT_VYUY: 320 val = CALC_WORD(pixel_per_line, 2, 8); 321 break; 322 } 323 324 return val; 325 } 326 327 static int vfe_word_per_line_by_bytes(u32 bytes_per_line) 328 { 329 return CALC_WORD(bytes_per_line, 1, 8); 330 } 331 332 static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, 333 u16 *width, u16 *height, u16 *bytesperline) 334 { 335 *width = pix->width; 336 *height = pix->height; 337 338 switch (pix->pixelformat) { 339 case V4L2_PIX_FMT_NV12: 340 case V4L2_PIX_FMT_NV21: 341 *bytesperline = pix->plane_fmt[0].bytesperline; 342 if (plane == 1) 343 *height /= 2; 344 break; 345 case V4L2_PIX_FMT_NV16: 346 case V4L2_PIX_FMT_NV61: 347 *bytesperline = pix->plane_fmt[0].bytesperline; 348 break; 349 case V4L2_PIX_FMT_YUYV: 350 case V4L2_PIX_FMT_YVYU: 351 case V4L2_PIX_FMT_VYUY: 352 case V4L2_PIX_FMT_UYVY: 353 *bytesperline = pix->plane_fmt[plane].bytesperline; 354 break; 355 } 356 } 357 358 static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, 359 struct v4l2_pix_format_mplane *pix, 360 u8 plane, u32 enable) 361 { 362 u32 reg; 363 364 if (enable) { 365 u16 width = 0, height = 0, bytesperline = 0, wpl; 366 367 vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline); 368 369 wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width); 370 371 reg = height - 1; 372 reg |= ((wpl + 3) / 4 - 1) << 16; 373 374 writel_relaxed(reg, vfe->base + 375 VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); 376 377 wpl = vfe_word_per_line_by_bytes(bytesperline); 378 379 reg = 0x3; 380 reg |= (height - 1) << 2; 381 reg |= ((wpl + 1) / 2) << 16; 382 383 writel_relaxed(reg, vfe->base + 384 VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); 385 } else { 386 writel_relaxed(0, vfe->base + 387 VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); 388 writel_relaxed(0, vfe->base + 389 VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); 390 } 391 } 392 393 static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per) 394 { 395 u32 reg; 396 397 reg = readl_relaxed(vfe->base + 398 VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); 399 400 reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK); 401 402 reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT) 403 & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK; 404 405 writel_relaxed(reg, 406 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); 407 } 408 409 static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm, 410 u32 pattern) 411 { 412 writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm)); 413 } 414 415 static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, 416 u16 offset, u16 depth) 417 { 418 u32 reg; 419 420 reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) | 421 depth; 422 writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm)); 423 } 424 425 static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm) 426 { 427 /* Enforce barrier between any outstanding register write */ 428 wmb(); 429 430 writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); 431 432 /* Use barrier to make sure bus reload is issued before anything else */ 433 wmb(); 434 } 435 436 static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr) 437 { 438 writel_relaxed(addr, 439 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm)); 440 } 441 442 static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr) 443 { 444 writel_relaxed(addr, 445 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm)); 446 } 447 448 static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm) 449 { 450 u32 reg; 451 452 reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS); 453 454 return (reg >> wm) & 0x1; 455 } 456 457 static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable) 458 { 459 if (enable) 460 writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG); 461 else 462 writel_relaxed(0, vfe->base + VFE_0_BUS_CFG); 463 } 464 465 static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm, 466 enum vfe_line_id id) 467 { 468 u32 reg; 469 470 reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS; 471 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg); 472 473 reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; 474 reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) & 475 VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK; 476 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg); 477 478 switch (id) { 479 case VFE_LINE_RDI0: 480 default: 481 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << 482 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 483 break; 484 case VFE_LINE_RDI1: 485 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << 486 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 487 break; 488 case VFE_LINE_RDI2: 489 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << 490 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 491 break; 492 } 493 494 if (wm % 2 == 1) 495 reg <<= 16; 496 497 vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); 498 } 499 500 static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm) 501 { 502 writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF, 503 vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); 504 } 505 506 static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm, 507 enum vfe_line_id id) 508 { 509 u32 reg; 510 511 reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; 512 vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg); 513 514 switch (id) { 515 case VFE_LINE_RDI0: 516 default: 517 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << 518 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 519 break; 520 case VFE_LINE_RDI1: 521 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << 522 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 523 break; 524 case VFE_LINE_RDI2: 525 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << 526 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 527 break; 528 } 529 530 if (wm % 2 == 1) 531 reg <<= 16; 532 533 vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); 534 } 535 536 static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, 537 u8 enable) 538 { 539 struct vfe_line *line = container_of(output, struct vfe_line, output); 540 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 541 u32 reg; 542 543 switch (p) { 544 case V4L2_PIX_FMT_NV12: 545 case V4L2_PIX_FMT_NV21: 546 case V4L2_PIX_FMT_NV16: 547 case V4L2_PIX_FMT_NV61: 548 reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA << 549 VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 550 551 if (output->wm_idx[0] % 2 == 1) 552 reg <<= 16; 553 554 if (enable) 555 vfe_reg_set(vfe, 556 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 557 reg); 558 else 559 vfe_reg_clr(vfe, 560 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 561 reg); 562 563 reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; 564 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16) 565 reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; 566 567 if (output->wm_idx[1] % 2 == 1) 568 reg <<= 16; 569 570 if (enable) 571 vfe_reg_set(vfe, 572 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), 573 reg); 574 else 575 vfe_reg_clr(vfe, 576 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), 577 reg); 578 break; 579 case V4L2_PIX_FMT_YUYV: 580 case V4L2_PIX_FMT_YVYU: 581 case V4L2_PIX_FMT_VYUY: 582 case V4L2_PIX_FMT_UYVY: 583 reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN; 584 reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; 585 586 if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU) 587 reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; 588 589 if (output->wm_idx[0] % 2 == 1) 590 reg <<= 16; 591 592 if (enable) 593 vfe_reg_set(vfe, 594 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 595 reg); 596 else 597 vfe_reg_clr(vfe, 598 VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 599 reg); 600 break; 601 default: 602 break; 603 } 604 } 605 606 static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line, 607 u8 enable) 608 { 609 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 610 u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF; 611 612 if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU && 613 p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY) 614 return; 615 616 if (enable) { 617 vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val); 618 } else { 619 vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val); 620 return; 621 } 622 623 val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE; 624 625 if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV) 626 val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL; 627 else 628 val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL; 629 630 writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG); 631 } 632 633 static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) 634 { 635 vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), 636 VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK); 637 638 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), 639 cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT); 640 } 641 642 static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) 643 { 644 vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); 645 646 /* Enforce barrier between line update and commit */ 647 wmb(); 648 649 writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); 650 651 /* Make sure register update is issued before further reg writes */ 652 wmb(); 653 } 654 655 static inline void vfe_reg_update_clear(struct vfe_device *vfe, 656 enum vfe_line_id line_id) 657 { 658 vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id); 659 } 660 661 static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, 662 enum vfe_line_id line_id, u8 enable) 663 { 664 u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) | 665 VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); 666 u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) | 667 VFE_0_IRQ_MASK_1_RDIn_SOF(line_id); 668 669 if (enable) { 670 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 671 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 672 } else { 673 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); 674 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); 675 } 676 } 677 678 static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp, 679 enum vfe_line_id line_id, u8 enable) 680 { 681 struct vfe_output *output = &vfe->line[line_id].output; 682 unsigned int i; 683 u32 irq_en0; 684 u32 irq_en1; 685 u32 comp_mask = 0; 686 687 irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF; 688 irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF; 689 irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp); 690 irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); 691 irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR; 692 for (i = 0; i < output->wm_num; i++) { 693 irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]); 694 comp_mask |= (1 << output->wm_idx[i]) << comp * 8; 695 } 696 697 if (enable) { 698 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 699 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 700 vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); 701 } else { 702 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); 703 vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); 704 vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); 705 } 706 } 707 708 static void vfe_enable_irq_common(struct vfe_device *vfe) 709 { 710 u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK; 711 u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION | 712 VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK; 713 714 vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 715 vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 716 } 717 718 static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) 719 { 720 u32 val, even_cfg, odd_cfg; 721 722 writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG); 723 724 val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD; 725 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0); 726 727 val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2; 728 writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1); 729 730 switch (line->fmt[MSM_VFE_PAD_SINK].code) { 731 case MEDIA_BUS_FMT_YUYV8_1X16: 732 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV; 733 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV; 734 break; 735 case MEDIA_BUS_FMT_YVYU8_1X16: 736 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU; 737 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU; 738 break; 739 case MEDIA_BUS_FMT_UYVY8_1X16: 740 default: 741 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY; 742 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY; 743 break; 744 case MEDIA_BUS_FMT_VYUY8_1X16: 745 even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY; 746 odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY; 747 break; 748 } 749 750 writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG); 751 writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); 752 } 753 754 static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) 755 { 756 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 757 u32 reg; 758 u16 input, output; 759 u8 interp_reso; 760 u32 phase_mult; 761 762 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG); 763 764 input = line->fmt[MSM_VFE_PAD_SINK].width - 1; 765 output = line->compose.width - 1; 766 reg = (output << 16) | input; 767 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE); 768 769 interp_reso = vfe_calc_interp_reso(input, output); 770 phase_mult = input * (1 << (14 + interp_reso)) / output; 771 reg = (interp_reso << 28) | phase_mult; 772 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE); 773 774 input = line->fmt[MSM_VFE_PAD_SINK].height - 1; 775 output = line->compose.height - 1; 776 reg = (output << 16) | input; 777 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE); 778 779 interp_reso = vfe_calc_interp_reso(input, output); 780 phase_mult = input * (1 << (14 + interp_reso)) / output; 781 reg = (interp_reso << 28) | phase_mult; 782 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE); 783 784 writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); 785 786 input = line->fmt[MSM_VFE_PAD_SINK].width - 1; 787 output = line->compose.width / 2 - 1; 788 reg = (output << 16) | input; 789 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); 790 791 interp_reso = vfe_calc_interp_reso(input, output); 792 phase_mult = input * (1 << (14 + interp_reso)) / output; 793 reg = (interp_reso << 28) | phase_mult; 794 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); 795 796 input = line->fmt[MSM_VFE_PAD_SINK].height - 1; 797 output = line->compose.height - 1; 798 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) 799 output = line->compose.height / 2 - 1; 800 reg = (output << 16) | input; 801 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); 802 803 interp_reso = vfe_calc_interp_reso(input, output); 804 phase_mult = input * (1 << (14 + interp_reso)) / output; 805 reg = (interp_reso << 28) | phase_mult; 806 writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); 807 } 808 809 static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line) 810 { 811 u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 812 u32 reg; 813 u16 first, last; 814 815 first = line->crop.left; 816 last = line->crop.left + line->crop.width - 1; 817 reg = (first << 16) | last; 818 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH); 819 820 first = line->crop.top; 821 last = line->crop.top + line->crop.height - 1; 822 reg = (first << 16) | last; 823 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT); 824 825 first = line->crop.left / 2; 826 last = line->crop.left / 2 + line->crop.width / 2 - 1; 827 reg = (first << 16) | last; 828 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH); 829 830 first = line->crop.top; 831 last = line->crop.top + line->crop.height - 1; 832 if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) { 833 first = line->crop.top / 2; 834 last = line->crop.top / 2 + line->crop.height / 2 - 1; 835 } 836 reg = (first << 16) | last; 837 writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT); 838 } 839 840 static void vfe_set_clamp_cfg(struct vfe_device *vfe) 841 { 842 u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 | 843 VFE_0_CLAMP_ENC_MAX_CFG_CH1 | 844 VFE_0_CLAMP_ENC_MAX_CFG_CH2; 845 846 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG); 847 848 val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 | 849 VFE_0_CLAMP_ENC_MIN_CFG_CH1 | 850 VFE_0_CLAMP_ENC_MIN_CFG_CH2; 851 852 writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); 853 } 854 855 static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) 856 { 857 /* empty */ 858 } 859 860 static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line) 861 { 862 u32 val; 863 864 switch (line->fmt[MSM_VFE_PAD_SINK].code) { 865 case MEDIA_BUS_FMT_YUYV8_1X16: 866 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR; 867 break; 868 case MEDIA_BUS_FMT_YVYU8_1X16: 869 val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB; 870 break; 871 case MEDIA_BUS_FMT_UYVY8_1X16: 872 default: 873 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY; 874 break; 875 case MEDIA_BUS_FMT_VYUY8_1X16: 876 val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY; 877 break; 878 } 879 880 val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN; 881 writel_relaxed(val, vfe->base + VFE_0_CORE_CFG); 882 883 val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; 884 val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16; 885 writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG); 886 887 val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; 888 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG); 889 890 val = line->fmt[MSM_VFE_PAD_SINK].height - 1; 891 writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG); 892 893 val = 0xffffffff; 894 writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG); 895 896 val = 0xffffffff; 897 writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN); 898 899 val = 0xffffffff; 900 writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN); 901 902 val = VFE_0_RDI_CFG_x_MIPI_EN_BITS; 903 vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val); 904 905 val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN; 906 writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG); 907 } 908 909 static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable) 910 { 911 u32 cmd; 912 913 cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE; 914 writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); 915 916 /* Make sure camif command is issued written before it is changed again */ 917 wmb(); 918 919 if (enable) 920 cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY; 921 else 922 cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY; 923 924 writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); 925 } 926 927 static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) 928 { 929 u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX | 930 VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE; 931 u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC | 932 VFE_0_MODULE_ZOOM_EN_CROP_ENC; 933 934 if (enable) { 935 vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens); 936 vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); 937 } else { 938 vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens); 939 vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); 940 } 941 } 942 943 static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev) 944 { 945 u32 val; 946 int ret; 947 948 ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS, 949 val, 950 (val & VFE_0_CAMIF_STATUS_HALT), 951 CAMIF_TIMEOUT_SLEEP_US, 952 CAMIF_TIMEOUT_ALL_US); 953 if (ret < 0) 954 dev_err(dev, "%s: camif stop timeout\n", __func__); 955 956 return ret; 957 } 958 959 /* 960 * vfe_isr - VFE module interrupt handler 961 * @irq: Interrupt line 962 * @dev: VFE device 963 * 964 * Return IRQ_HANDLED on success 965 */ 966 static irqreturn_t vfe_isr(int irq, void *dev) 967 { 968 struct vfe_device *vfe = dev; 969 u32 value0, value1; 970 int i, j; 971 972 vfe->res->hw_ops->isr_read(vfe, &value0, &value1); 973 974 dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", 975 value0, value1); 976 977 if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) 978 vfe->isr_ops.reset_ack(vfe); 979 980 if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION) 981 vfe->res->hw_ops->violation_read(vfe); 982 983 if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) 984 vfe->isr_ops.halt_ack(vfe); 985 986 for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) 987 if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i)) 988 vfe->isr_ops.reg_update(vfe, i); 989 990 if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF) 991 vfe->isr_ops.sof(vfe, VFE_LINE_PIX); 992 993 for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) 994 if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i)) 995 vfe->isr_ops.sof(vfe, i); 996 997 for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++) 998 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) { 999 vfe->isr_ops.comp_done(vfe, i); 1000 for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++) 1001 if (vfe->wm_output_map[j] == VFE_LINE_PIX) 1002 value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j); 1003 } 1004 1005 for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) 1006 if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i)) 1007 vfe->isr_ops.wm_done(vfe, i); 1008 1009 return IRQ_HANDLED; 1010 } 1011 1012 static u16 vfe_get_ub_size(u8 vfe_id) 1013 { 1014 /* On VFE4.8 the ub-size is the same on both instances */ 1015 return MSM_VFE_VFE0_UB_SIZE_RDI; 1016 } 1017 1018 static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) 1019 { 1020 if (enable) 1021 writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), 1022 vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); 1023 else 1024 writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), 1025 vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); 1026 1027 /* The WM must be enabled before sending other commands */ 1028 wmb(); 1029 } 1030 1031 static void vfe_set_qos(struct vfe_device *vfe) 1032 { 1033 u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; 1034 u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG; 1035 u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG; 1036 u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; 1037 1038 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); 1039 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); 1040 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); 1041 writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); 1042 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); 1043 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); 1044 writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); 1045 writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); 1046 } 1047 1048 static void vfe_set_ds(struct vfe_device *vfe) 1049 { 1050 u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; 1051 u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; 1052 1053 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); 1054 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); 1055 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); 1056 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); 1057 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); 1058 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); 1059 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); 1060 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); 1061 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); 1062 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); 1063 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); 1064 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); 1065 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); 1066 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); 1067 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); 1068 writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); 1069 writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); 1070 } 1071 1072 static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) 1073 { 1074 *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); 1075 *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); 1076 1077 writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); 1078 writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); 1079 1080 /* Enforce barrier between local & global IRQ clear */ 1081 wmb(); 1082 writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); 1083 } 1084 1085 static void vfe_violation_read(struct vfe_device *vfe) 1086 { 1087 u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); 1088 1089 pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); 1090 } 1091 1092 static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = { 1093 .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, 1094 .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, 1095 .bus_enable_wr_if = vfe_bus_enable_wr_if, 1096 .bus_reload_wm = vfe_bus_reload_wm, 1097 .camif_wait_for_stop = vfe_camif_wait_for_stop, 1098 .enable_irq_common = vfe_enable_irq_common, 1099 .enable_irq_pix_line = vfe_enable_irq_pix_line, 1100 .enable_irq_wm_line = vfe_enable_irq_wm_line, 1101 .get_ub_size = vfe_get_ub_size, 1102 .halt_clear = vfe_halt_clear, 1103 .halt_request = vfe_halt_request, 1104 .set_camif_cfg = vfe_set_camif_cfg, 1105 .set_camif_cmd = vfe_set_camif_cmd, 1106 .set_cgc_override = vfe_set_cgc_override, 1107 .set_clamp_cfg = vfe_set_clamp_cfg, 1108 .set_crop_cfg = vfe_set_crop_cfg, 1109 .set_demux_cfg = vfe_set_demux_cfg, 1110 .set_ds = vfe_set_ds, 1111 .set_module_cfg = vfe_set_module_cfg, 1112 .set_qos = vfe_set_qos, 1113 .set_rdi_cid = vfe_set_rdi_cid, 1114 .set_realign_cfg = vfe_set_realign_cfg, 1115 .set_scale_cfg = vfe_set_scale_cfg, 1116 .set_xbar_cfg = vfe_set_xbar_cfg, 1117 .wm_enable = vfe_wm_enable, 1118 .wm_frame_based = vfe_wm_frame_based, 1119 .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, 1120 .wm_line_based = vfe_wm_line_based, 1121 .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, 1122 .wm_set_framedrop_period = vfe_wm_set_framedrop_period, 1123 .wm_set_ping_addr = vfe_wm_set_ping_addr, 1124 .wm_set_pong_addr = vfe_wm_set_pong_addr, 1125 .wm_set_subsample = vfe_wm_set_subsample, 1126 .wm_set_ub_cfg = vfe_wm_set_ub_cfg, 1127 }; 1128 1129 static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) 1130 { 1131 vfe->isr_ops = vfe_isr_ops_gen1; 1132 vfe->ops_gen1 = &vfe_ops_gen1_4_8; 1133 vfe->video_ops = vfe_video_ops_gen1; 1134 } 1135 1136 const struct vfe_hw_ops vfe_ops_4_8 = { 1137 .global_reset = vfe_global_reset, 1138 .hw_version = vfe_hw_version, 1139 .isr_read = vfe_isr_read, 1140 .isr = vfe_isr, 1141 .pm_domain_off = vfe_pm_domain_off, 1142 .pm_domain_on = vfe_pm_domain_on, 1143 .reg_update_clear = vfe_reg_update_clear, 1144 .reg_update = vfe_reg_update, 1145 .subdev_init = vfe_subdev_init, 1146 .vfe_disable = vfe_gen1_disable, 1147 .vfe_enable = vfe_gen1_enable, 1148 .vfe_halt = vfe_gen1_halt, 1149 .violation_read = vfe_violation_read, 1150 }; 1151