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