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