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