162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * camss-vfe-4-8.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. 862306a36Sopenharmony_ci * Copyright (C) 2015-2021 Linaro Ltd. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/device.h> 1262306a36Sopenharmony_ci#include <linux/interrupt.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/iopoll.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "camss.h" 1762306a36Sopenharmony_ci#include "camss-vfe.h" 1862306a36Sopenharmony_ci#include "camss-vfe-gen1.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define VFE_0_HW_VERSION 0x000 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD 0x018 2362306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_CORE BIT(0) 2462306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_CAMIF BIT(1) 2562306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_BUS BIT(2) 2662306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG BIT(3) 2762306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_REGISTER BIT(4) 2862306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_PM BIT(5) 2962306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(6) 3062306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_TESTGEN BIT(7) 3162306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_DSP BIT(8) 3262306a36Sopenharmony_ci#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC BIT(9) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define VFE_0_MODULE_LENS_EN 0x040 3562306a36Sopenharmony_ci#define VFE_0_MODULE_LENS_EN_DEMUX BIT(2) 3662306a36Sopenharmony_ci#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE BIT(3) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#define VFE_0_MODULE_ZOOM_EN 0x04c 3962306a36Sopenharmony_ci#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC BIT(1) 4062306a36Sopenharmony_ci#define VFE_0_MODULE_ZOOM_EN_CROP_ENC BIT(2) 4162306a36Sopenharmony_ci#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF BIT(9) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define VFE_0_CORE_CFG 0x050 4462306a36Sopenharmony_ci#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR 0x4 4562306a36Sopenharmony_ci#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB 0x5 4662306a36Sopenharmony_ci#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY 0x6 4762306a36Sopenharmony_ci#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY 0x7 4862306a36Sopenharmony_ci#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN BIT(4) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define VFE_0_IRQ_CMD 0x058 5162306a36Sopenharmony_ci#define VFE_0_IRQ_CMD_GLOBAL_CLEAR BIT(0) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0 0x05c 5462306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_CAMIF_SOF BIT(0) 5562306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_CAMIF_EOF BIT(1) 5662306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n) BIT((n) + 5) 5762306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n) \ 5862306a36Sopenharmony_ci ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)) 5962306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) 6062306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) 6162306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_0_RESET_ACK BIT(31) 6262306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1 0x060 6362306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1_CAMIF_ERROR BIT(0) 6462306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1_VIOLATION BIT(7) 6562306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK BIT(8) 6662306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9) 6762306a36Sopenharmony_ci#define VFE_0_IRQ_MASK_1_RDIn_SOF(n) BIT((n) + 29) 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#define VFE_0_IRQ_CLEAR_0 0x064 7062306a36Sopenharmony_ci#define VFE_0_IRQ_CLEAR_1 0x068 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0 0x06c 7362306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_CAMIF_SOF BIT(0) 7462306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n) BIT((n) + 5) 7562306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n) \ 7662306a36Sopenharmony_ci ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)) 7762306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n) BIT((n) + 8) 7862306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n) BIT((n) + 25) 7962306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_0_RESET_ACK BIT(31) 8062306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_1 0x070 8162306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_1_VIOLATION BIT(7) 8262306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK BIT(8) 8362306a36Sopenharmony_ci#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n) BIT((n) + 29) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define VFE_0_IRQ_COMPOSITE_MASK_0 0x074 8662306a36Sopenharmony_ci#define VFE_0_VIOLATION_STATUS 0x07c 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define VFE_0_BUS_CMD 0x80 8962306a36Sopenharmony_ci#define VFE_0_BUS_CMD_Mx_RLD_CMD(x) BIT(x) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define VFE_0_BUS_CFG 0x084 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x(x) (0x90 + 0x4 * ((x) / 2)) 9462306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN BIT(2) 9562306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN BIT(3) 9662306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA (0x1 << 4) 9762306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER (0x2 << 4) 9862306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA (0x3 << 4) 9962306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT 8 10062306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA 0x0 10162306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 0xc 10262306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 0xd 10362306a36Sopenharmony_ci#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 0xe 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n) (0x0a0 + 0x2c * (n)) 10662306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT 0 10762306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n) (0x0a4 + 0x2c * (n)) 10862306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n) (0x0ac + 0x2c * (n)) 10962306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n) (0x0b4 + 0x2c * (n)) 11062306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT 1 11162306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2 11262306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK (0x1f << 2) 11362306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n) (0x0b8 + 0x2c * (n)) 11462306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16 11562306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n) (0x0bc + 0x2c * (n)) 11662306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n) (0x0c0 + 0x2c * (n)) 11762306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n) \ 11862306a36Sopenharmony_ci (0x0c4 + 0x2c * (n)) 11962306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n) \ 12062306a36Sopenharmony_ci (0x0c8 + 0x2c * (n)) 12162306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF 0xffffffff 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define VFE_0_BUS_PING_PONG_STATUS 0x338 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#define VFE_0_BUS_BDG_CMD 0x400 12662306a36Sopenharmony_ci#define VFE_0_BUS_BDG_CMD_HALT_REQ 1 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_0 0x404 12962306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_0_CFG 0xaaa5aaa5 13062306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_1 0x408 13162306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_2 0x40c 13262306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_3 0x410 13362306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_3_CFG 0xaa55aaa5 13462306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_4 0x414 13562306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_4_CFG 0xaa55aa55 13662306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_5 0x418 13762306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_6 0x41c 13862306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_7 0x420 13962306a36Sopenharmony_ci#define VFE_0_BUS_BDG_QOS_CFG_7_CFG 0x0005aa55 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_0 0x424 14262306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_0_CFG 0xcccc1111 14362306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_1 0x428 14462306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_2 0x42c 14562306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_3 0x430 14662306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_4 0x434 14762306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_5 0x438 14862306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_6 0x43c 14962306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_7 0x440 15062306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_8 0x444 15162306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_9 0x448 15262306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_10 0x44c 15362306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_11 0x450 15462306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_12 0x454 15562306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_13 0x458 15662306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_14 0x45c 15762306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_15 0x460 15862306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_16 0x464 15962306a36Sopenharmony_ci#define VFE_0_BUS_BDG_DS_CFG_16_CFG 0x00000110 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x(x) (0x46c + (0x4 * (x))) 16262306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT 28 16362306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK (0xf << 28) 16462306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT 4 16562306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK (0xf << 4) 16662306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_RDI_EN_BIT BIT(2) 16762306a36Sopenharmony_ci#define VFE_0_RDI_CFG_x_MIPI_EN_BITS 0x3 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci#define VFE_0_CAMIF_CMD 0x478 17062306a36Sopenharmony_ci#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY 0 17162306a36Sopenharmony_ci#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY 1 17262306a36Sopenharmony_ci#define VFE_0_CAMIF_CMD_NO_CHANGE 3 17362306a36Sopenharmony_ci#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS BIT(2) 17462306a36Sopenharmony_ci#define VFE_0_CAMIF_CFG 0x47c 17562306a36Sopenharmony_ci#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN BIT(6) 17662306a36Sopenharmony_ci#define VFE_0_CAMIF_FRAME_CFG 0x484 17762306a36Sopenharmony_ci#define VFE_0_CAMIF_WINDOW_WIDTH_CFG 0x488 17862306a36Sopenharmony_ci#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG 0x48c 17962306a36Sopenharmony_ci#define VFE_0_CAMIF_SUBSAMPLE_CFG 0x490 18062306a36Sopenharmony_ci#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN 0x498 18162306a36Sopenharmony_ci#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN 0x49c 18262306a36Sopenharmony_ci#define VFE_0_CAMIF_STATUS 0x4a4 18362306a36Sopenharmony_ci#define VFE_0_CAMIF_STATUS_HALT BIT(31) 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci#define VFE_0_REG_UPDATE 0x4ac 18662306a36Sopenharmony_ci#define VFE_0_REG_UPDATE_RDIn(n) BIT(1 + (n)) 18762306a36Sopenharmony_ci#define VFE_0_REG_UPDATE_line_n(n) \ 18862306a36Sopenharmony_ci ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n)) 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#define VFE_0_DEMUX_CFG 0x560 19162306a36Sopenharmony_ci#define VFE_0_DEMUX_CFG_PERIOD 0x3 19262306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_0 0x564 19362306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_0_CH0_EVEN (0x80 << 0) 19462306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_0_CH0_ODD (0x80 << 16) 19562306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_1 0x568 19662306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_1_CH1 (0x80 << 0) 19762306a36Sopenharmony_ci#define VFE_0_DEMUX_GAIN_1_CH2 (0x80 << 16) 19862306a36Sopenharmony_ci#define VFE_0_DEMUX_EVEN_CFG 0x574 19962306a36Sopenharmony_ci#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV 0x9cac 20062306a36Sopenharmony_ci#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU 0xac9c 20162306a36Sopenharmony_ci#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY 0xc9ca 20262306a36Sopenharmony_ci#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY 0xcac9 20362306a36Sopenharmony_ci#define VFE_0_DEMUX_ODD_CFG 0x578 20462306a36Sopenharmony_ci#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV 0x9cac 20562306a36Sopenharmony_ci#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU 0xac9c 20662306a36Sopenharmony_ci#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY 0xc9ca 20762306a36Sopenharmony_ci#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY 0xcac9 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_Y_CFG 0x91c 21062306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE 0x920 21162306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_Y_H_PHASE 0x924 21262306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE 0x934 21362306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_Y_V_PHASE 0x938 21462306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_CBCR_CFG 0x948 21562306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE 0x94c 21662306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_CBCR_H_PHASE 0x950 21762306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE 0x960 21862306a36Sopenharmony_ci#define VFE_0_SCALE_ENC_CBCR_V_PHASE 0x964 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci#define VFE_0_CROP_ENC_Y_WIDTH 0x974 22162306a36Sopenharmony_ci#define VFE_0_CROP_ENC_Y_HEIGHT 0x978 22262306a36Sopenharmony_ci#define VFE_0_CROP_ENC_CBCR_WIDTH 0x97c 22362306a36Sopenharmony_ci#define VFE_0_CROP_ENC_CBCR_HEIGHT 0x980 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MAX_CFG 0x984 22662306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MAX_CFG_CH0 (0xff << 0) 22762306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MAX_CFG_CH1 (0xff << 8) 22862306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MAX_CFG_CH2 (0xff << 16) 22962306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MIN_CFG 0x988 23062306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MIN_CFG_CH0 (0x0 << 0) 23162306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MIN_CFG_CH1 (0x0 << 8) 23262306a36Sopenharmony_ci#define VFE_0_CLAMP_ENC_MIN_CFG_CH2 (0x0 << 16) 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci#define VFE_0_REALIGN_BUF_CFG 0xaac 23562306a36Sopenharmony_ci#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL BIT(2) 23662306a36Sopenharmony_ci#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL BIT(3) 23762306a36Sopenharmony_ci#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE BIT(4) 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_CMD 0xcec 24062306a36Sopenharmony_ci#define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x) (2 * (x)) 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci#define CAMIF_TIMEOUT_SLEEP_US 1000 24362306a36Sopenharmony_ci#define CAMIF_TIMEOUT_ALL_US 1000000 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci#define MSM_VFE_VFE0_UB_SIZE 2047 24662306a36Sopenharmony_ci#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3) 24762306a36Sopenharmony_ci#define MSM_VFE_VFE1_UB_SIZE 1535 24862306a36Sopenharmony_ci#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3) 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic u32 vfe_hw_version(struct vfe_device *vfe) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci dev_dbg(vfe->camss->dev, "VFE HW Version = 0x%08x\n", hw_version); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci return hw_version; 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci u32 bits = readl_relaxed(vfe->base + reg); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci writel_relaxed(bits & ~clr_bits, vfe->base + reg); 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci u32 bits = readl_relaxed(vfe->base + reg); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci writel_relaxed(bits | set_bits, vfe->base + reg); 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic void vfe_global_reset(struct vfe_device *vfe) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC | 27662306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_DSP | 27762306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_TESTGEN | 27862306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_BUS_MISR | 27962306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_PM | 28062306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_REGISTER | 28162306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_BUS_BDG | 28262306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_BUS | 28362306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_CAMIF | 28462306a36Sopenharmony_ci VFE_0_GLOBAL_RESET_CMD_CORE; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0); 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci /* Enforce barrier between IRQ mask setup and global reset */ 28962306a36Sopenharmony_ci wmb(); 29062306a36Sopenharmony_ci writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD); 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic void vfe_halt_request(struct vfe_device *vfe) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ, 29662306a36Sopenharmony_ci vfe->base + VFE_0_BUS_BDG_CMD); 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic void vfe_halt_clear(struct vfe_device *vfe) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD); 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cistatic void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci if (enable) 30762306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), 30862306a36Sopenharmony_ci 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); 30962306a36Sopenharmony_ci else 31062306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm), 31162306a36Sopenharmony_ci 1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT); 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N)) 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cistatic int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci int val = 0; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci switch (format) { 32162306a36Sopenharmony_ci case V4L2_PIX_FMT_NV12: 32262306a36Sopenharmony_ci case V4L2_PIX_FMT_NV21: 32362306a36Sopenharmony_ci case V4L2_PIX_FMT_NV16: 32462306a36Sopenharmony_ci case V4L2_PIX_FMT_NV61: 32562306a36Sopenharmony_ci val = CALC_WORD(pixel_per_line, 1, 8); 32662306a36Sopenharmony_ci break; 32762306a36Sopenharmony_ci case V4L2_PIX_FMT_YUYV: 32862306a36Sopenharmony_ci case V4L2_PIX_FMT_YVYU: 32962306a36Sopenharmony_ci case V4L2_PIX_FMT_UYVY: 33062306a36Sopenharmony_ci case V4L2_PIX_FMT_VYUY: 33162306a36Sopenharmony_ci val = CALC_WORD(pixel_per_line, 2, 8); 33262306a36Sopenharmony_ci break; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return val; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic int vfe_word_per_line_by_bytes(u32 bytes_per_line) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci return CALC_WORD(bytes_per_line, 1, 8); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane, 34462306a36Sopenharmony_ci u16 *width, u16 *height, u16 *bytesperline) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci *width = pix->width; 34762306a36Sopenharmony_ci *height = pix->height; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci switch (pix->pixelformat) { 35062306a36Sopenharmony_ci case V4L2_PIX_FMT_NV12: 35162306a36Sopenharmony_ci case V4L2_PIX_FMT_NV21: 35262306a36Sopenharmony_ci *bytesperline = pix->plane_fmt[0].bytesperline; 35362306a36Sopenharmony_ci if (plane == 1) 35462306a36Sopenharmony_ci *height /= 2; 35562306a36Sopenharmony_ci break; 35662306a36Sopenharmony_ci case V4L2_PIX_FMT_NV16: 35762306a36Sopenharmony_ci case V4L2_PIX_FMT_NV61: 35862306a36Sopenharmony_ci *bytesperline = pix->plane_fmt[0].bytesperline; 35962306a36Sopenharmony_ci break; 36062306a36Sopenharmony_ci case V4L2_PIX_FMT_YUYV: 36162306a36Sopenharmony_ci case V4L2_PIX_FMT_YVYU: 36262306a36Sopenharmony_ci case V4L2_PIX_FMT_VYUY: 36362306a36Sopenharmony_ci case V4L2_PIX_FMT_UYVY: 36462306a36Sopenharmony_ci *bytesperline = pix->plane_fmt[plane].bytesperline; 36562306a36Sopenharmony_ci break; 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistatic void vfe_wm_line_based(struct vfe_device *vfe, u32 wm, 37062306a36Sopenharmony_ci struct v4l2_pix_format_mplane *pix, 37162306a36Sopenharmony_ci u8 plane, u32 enable) 37262306a36Sopenharmony_ci{ 37362306a36Sopenharmony_ci u32 reg; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci if (enable) { 37662306a36Sopenharmony_ci u16 width = 0, height = 0, bytesperline = 0, wpl; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci reg = height - 1; 38362306a36Sopenharmony_ci reg |= ((wpl + 3) / 4 - 1) << 16; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + 38662306a36Sopenharmony_ci VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci wpl = vfe_word_per_line_by_bytes(bytesperline); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci reg = 0x3; 39162306a36Sopenharmony_ci reg |= (height - 1) << 2; 39262306a36Sopenharmony_ci reg |= ((wpl + 1) / 2) << 16; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + 39562306a36Sopenharmony_ci VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); 39662306a36Sopenharmony_ci } else { 39762306a36Sopenharmony_ci writel_relaxed(0, vfe->base + 39862306a36Sopenharmony_ci VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm)); 39962306a36Sopenharmony_ci writel_relaxed(0, vfe->base + 40062306a36Sopenharmony_ci VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm)); 40162306a36Sopenharmony_ci } 40262306a36Sopenharmony_ci} 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistatic void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci u32 reg; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci reg = readl_relaxed(vfe->base + 40962306a36Sopenharmony_ci VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK); 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT) 41462306a36Sopenharmony_ci & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci writel_relaxed(reg, 41762306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm)); 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_cistatic void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm, 42162306a36Sopenharmony_ci u32 pattern) 42262306a36Sopenharmony_ci{ 42362306a36Sopenharmony_ci writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm)); 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm, 42762306a36Sopenharmony_ci u16 offset, u16 depth) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci u32 reg; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) | 43262306a36Sopenharmony_ci depth; 43362306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm)); 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci /* Enforce barrier between any outstanding register write */ 43962306a36Sopenharmony_ci wmb(); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci /* Use barrier to make sure bus reload is issued before anything else */ 44462306a36Sopenharmony_ci wmb(); 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr) 44862306a36Sopenharmony_ci{ 44962306a36Sopenharmony_ci writel_relaxed(addr, 45062306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm)); 45162306a36Sopenharmony_ci} 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_cistatic void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr) 45462306a36Sopenharmony_ci{ 45562306a36Sopenharmony_ci writel_relaxed(addr, 45662306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm)); 45762306a36Sopenharmony_ci} 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_cistatic int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm) 46062306a36Sopenharmony_ci{ 46162306a36Sopenharmony_ci u32 reg; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci return (reg >> wm) & 0x1; 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci if (enable) 47162306a36Sopenharmony_ci writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG); 47262306a36Sopenharmony_ci else 47362306a36Sopenharmony_ci writel_relaxed(0, vfe->base + VFE_0_BUS_CFG); 47462306a36Sopenharmony_ci} 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm, 47762306a36Sopenharmony_ci enum vfe_line_id id) 47862306a36Sopenharmony_ci{ 47962306a36Sopenharmony_ci u32 reg; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS; 48262306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; 48562306a36Sopenharmony_ci reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) & 48662306a36Sopenharmony_ci VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK; 48762306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci switch (id) { 49062306a36Sopenharmony_ci case VFE_LINE_RDI0: 49162306a36Sopenharmony_ci default: 49262306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << 49362306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 49462306a36Sopenharmony_ci break; 49562306a36Sopenharmony_ci case VFE_LINE_RDI1: 49662306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << 49762306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 49862306a36Sopenharmony_ci break; 49962306a36Sopenharmony_ci case VFE_LINE_RDI2: 50062306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << 50162306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 50262306a36Sopenharmony_ci break; 50362306a36Sopenharmony_ci } 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci if (wm % 2 == 1) 50662306a36Sopenharmony_ci reg <<= 16; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); 50962306a36Sopenharmony_ci} 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm) 51262306a36Sopenharmony_ci{ 51362306a36Sopenharmony_ci writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF, 51462306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm)); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_cistatic void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm, 51862306a36Sopenharmony_ci enum vfe_line_id id) 51962306a36Sopenharmony_ci{ 52062306a36Sopenharmony_ci u32 reg; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci reg = VFE_0_RDI_CFG_x_RDI_EN_BIT; 52362306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg); 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci switch (id) { 52662306a36Sopenharmony_ci case VFE_LINE_RDI0: 52762306a36Sopenharmony_ci default: 52862306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 << 52962306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 53062306a36Sopenharmony_ci break; 53162306a36Sopenharmony_ci case VFE_LINE_RDI1: 53262306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 << 53362306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 53462306a36Sopenharmony_ci break; 53562306a36Sopenharmony_ci case VFE_LINE_RDI2: 53662306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 << 53762306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 53862306a36Sopenharmony_ci break; 53962306a36Sopenharmony_ci } 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci if (wm % 2 == 1) 54262306a36Sopenharmony_ci reg <<= 16; 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg); 54562306a36Sopenharmony_ci} 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_cistatic void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, 54862306a36Sopenharmony_ci u8 enable) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci struct vfe_line *line = container_of(output, struct vfe_line, output); 55162306a36Sopenharmony_ci u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 55262306a36Sopenharmony_ci u32 reg; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci switch (p) { 55562306a36Sopenharmony_ci case V4L2_PIX_FMT_NV12: 55662306a36Sopenharmony_ci case V4L2_PIX_FMT_NV21: 55762306a36Sopenharmony_ci case V4L2_PIX_FMT_NV16: 55862306a36Sopenharmony_ci case V4L2_PIX_FMT_NV61: 55962306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA << 56062306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci if (output->wm_idx[0] % 2 == 1) 56362306a36Sopenharmony_ci reg <<= 16; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci if (enable) 56662306a36Sopenharmony_ci vfe_reg_set(vfe, 56762306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 56862306a36Sopenharmony_ci reg); 56962306a36Sopenharmony_ci else 57062306a36Sopenharmony_ci vfe_reg_clr(vfe, 57162306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 57262306a36Sopenharmony_ci reg); 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; 57562306a36Sopenharmony_ci if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16) 57662306a36Sopenharmony_ci reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci if (output->wm_idx[1] % 2 == 1) 57962306a36Sopenharmony_ci reg <<= 16; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci if (enable) 58262306a36Sopenharmony_ci vfe_reg_set(vfe, 58362306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), 58462306a36Sopenharmony_ci reg); 58562306a36Sopenharmony_ci else 58662306a36Sopenharmony_ci vfe_reg_clr(vfe, 58762306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]), 58862306a36Sopenharmony_ci reg); 58962306a36Sopenharmony_ci break; 59062306a36Sopenharmony_ci case V4L2_PIX_FMT_YUYV: 59162306a36Sopenharmony_ci case V4L2_PIX_FMT_YVYU: 59262306a36Sopenharmony_ci case V4L2_PIX_FMT_VYUY: 59362306a36Sopenharmony_ci case V4L2_PIX_FMT_UYVY: 59462306a36Sopenharmony_ci reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN; 59562306a36Sopenharmony_ci reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU) 59862306a36Sopenharmony_ci reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci if (output->wm_idx[0] % 2 == 1) 60162306a36Sopenharmony_ci reg <<= 16; 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci if (enable) 60462306a36Sopenharmony_ci vfe_reg_set(vfe, 60562306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 60662306a36Sopenharmony_ci reg); 60762306a36Sopenharmony_ci else 60862306a36Sopenharmony_ci vfe_reg_clr(vfe, 60962306a36Sopenharmony_ci VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]), 61062306a36Sopenharmony_ci reg); 61162306a36Sopenharmony_ci break; 61262306a36Sopenharmony_ci default: 61362306a36Sopenharmony_ci break; 61462306a36Sopenharmony_ci } 61562306a36Sopenharmony_ci} 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_cistatic void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line, 61862306a36Sopenharmony_ci u8 enable) 61962306a36Sopenharmony_ci{ 62062306a36Sopenharmony_ci u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 62162306a36Sopenharmony_ci u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU && 62462306a36Sopenharmony_ci p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY) 62562306a36Sopenharmony_ci return; 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci if (enable) { 62862306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val); 62962306a36Sopenharmony_ci } else { 63062306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val); 63162306a36Sopenharmony_ci return; 63262306a36Sopenharmony_ci } 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV) 63762306a36Sopenharmony_ci val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL; 63862306a36Sopenharmony_ci else 63962306a36Sopenharmony_ci val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG); 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_cistatic void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid) 64562306a36Sopenharmony_ci{ 64662306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), 64762306a36Sopenharmony_ci VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK); 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), 65062306a36Sopenharmony_ci cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT); 65162306a36Sopenharmony_ci} 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_cistatic void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id) 65462306a36Sopenharmony_ci{ 65562306a36Sopenharmony_ci vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id); 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci /* Enforce barrier between line update and commit */ 65862306a36Sopenharmony_ci wmb(); 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* Make sure register update is issued before further reg writes */ 66362306a36Sopenharmony_ci wmb(); 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_cistatic inline void vfe_reg_update_clear(struct vfe_device *vfe, 66762306a36Sopenharmony_ci enum vfe_line_id line_id) 66862306a36Sopenharmony_ci{ 66962306a36Sopenharmony_ci vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id); 67062306a36Sopenharmony_ci} 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_cistatic void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm, 67362306a36Sopenharmony_ci enum vfe_line_id line_id, u8 enable) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) | 67662306a36Sopenharmony_ci VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); 67762306a36Sopenharmony_ci u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) | 67862306a36Sopenharmony_ci VFE_0_IRQ_MASK_1_RDIn_SOF(line_id); 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci if (enable) { 68162306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 68262306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 68362306a36Sopenharmony_ci } else { 68462306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); 68562306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); 68662306a36Sopenharmony_ci } 68762306a36Sopenharmony_ci} 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_cistatic void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp, 69062306a36Sopenharmony_ci enum vfe_line_id line_id, u8 enable) 69162306a36Sopenharmony_ci{ 69262306a36Sopenharmony_ci struct vfe_output *output = &vfe->line[line_id].output; 69362306a36Sopenharmony_ci unsigned int i; 69462306a36Sopenharmony_ci u32 irq_en0; 69562306a36Sopenharmony_ci u32 irq_en1; 69662306a36Sopenharmony_ci u32 comp_mask = 0; 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF; 69962306a36Sopenharmony_ci irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF; 70062306a36Sopenharmony_ci irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp); 70162306a36Sopenharmony_ci irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id); 70262306a36Sopenharmony_ci irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR; 70362306a36Sopenharmony_ci for (i = 0; i < output->wm_num; i++) { 70462306a36Sopenharmony_ci irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]); 70562306a36Sopenharmony_ci comp_mask |= (1 << output->wm_idx[i]) << comp * 8; 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci if (enable) { 70962306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 71062306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 71162306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); 71262306a36Sopenharmony_ci } else { 71362306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0); 71462306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1); 71562306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask); 71662306a36Sopenharmony_ci } 71762306a36Sopenharmony_ci} 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_cistatic void vfe_enable_irq_common(struct vfe_device *vfe) 72062306a36Sopenharmony_ci{ 72162306a36Sopenharmony_ci u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK; 72262306a36Sopenharmony_ci u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION | 72362306a36Sopenharmony_ci VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0); 72662306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1); 72762306a36Sopenharmony_ci} 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_cistatic void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line) 73062306a36Sopenharmony_ci{ 73162306a36Sopenharmony_ci u32 val, even_cfg, odd_cfg; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG); 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD; 73662306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2; 73962306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1); 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci switch (line->fmt[MSM_VFE_PAD_SINK].code) { 74262306a36Sopenharmony_ci case MEDIA_BUS_FMT_YUYV8_2X8: 74362306a36Sopenharmony_ci even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV; 74462306a36Sopenharmony_ci odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV; 74562306a36Sopenharmony_ci break; 74662306a36Sopenharmony_ci case MEDIA_BUS_FMT_YVYU8_2X8: 74762306a36Sopenharmony_ci even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU; 74862306a36Sopenharmony_ci odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU; 74962306a36Sopenharmony_ci break; 75062306a36Sopenharmony_ci case MEDIA_BUS_FMT_UYVY8_2X8: 75162306a36Sopenharmony_ci default: 75262306a36Sopenharmony_ci even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY; 75362306a36Sopenharmony_ci odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY; 75462306a36Sopenharmony_ci break; 75562306a36Sopenharmony_ci case MEDIA_BUS_FMT_VYUY8_2X8: 75662306a36Sopenharmony_ci even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY; 75762306a36Sopenharmony_ci odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY; 75862306a36Sopenharmony_ci break; 75962306a36Sopenharmony_ci } 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG); 76262306a36Sopenharmony_ci writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG); 76362306a36Sopenharmony_ci} 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_cistatic void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line) 76662306a36Sopenharmony_ci{ 76762306a36Sopenharmony_ci u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 76862306a36Sopenharmony_ci u32 reg; 76962306a36Sopenharmony_ci u16 input, output; 77062306a36Sopenharmony_ci u8 interp_reso; 77162306a36Sopenharmony_ci u32 phase_mult; 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci input = line->fmt[MSM_VFE_PAD_SINK].width - 1; 77662306a36Sopenharmony_ci output = line->compose.width - 1; 77762306a36Sopenharmony_ci reg = (output << 16) | input; 77862306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE); 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci interp_reso = vfe_calc_interp_reso(input, output); 78162306a36Sopenharmony_ci phase_mult = input * (1 << (14 + interp_reso)) / output; 78262306a36Sopenharmony_ci reg = (interp_reso << 28) | phase_mult; 78362306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci input = line->fmt[MSM_VFE_PAD_SINK].height - 1; 78662306a36Sopenharmony_ci output = line->compose.height - 1; 78762306a36Sopenharmony_ci reg = (output << 16) | input; 78862306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE); 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci interp_reso = vfe_calc_interp_reso(input, output); 79162306a36Sopenharmony_ci phase_mult = input * (1 << (14 + interp_reso)) / output; 79262306a36Sopenharmony_ci reg = (interp_reso << 28) | phase_mult; 79362306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE); 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG); 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci input = line->fmt[MSM_VFE_PAD_SINK].width - 1; 79862306a36Sopenharmony_ci output = line->compose.width / 2 - 1; 79962306a36Sopenharmony_ci reg = (output << 16) | input; 80062306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE); 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci interp_reso = vfe_calc_interp_reso(input, output); 80362306a36Sopenharmony_ci phase_mult = input * (1 << (14 + interp_reso)) / output; 80462306a36Sopenharmony_ci reg = (interp_reso << 28) | phase_mult; 80562306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci input = line->fmt[MSM_VFE_PAD_SINK].height - 1; 80862306a36Sopenharmony_ci output = line->compose.height - 1; 80962306a36Sopenharmony_ci if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) 81062306a36Sopenharmony_ci output = line->compose.height / 2 - 1; 81162306a36Sopenharmony_ci reg = (output << 16) | input; 81262306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE); 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci interp_reso = vfe_calc_interp_reso(input, output); 81562306a36Sopenharmony_ci phase_mult = input * (1 << (14 + interp_reso)) / output; 81662306a36Sopenharmony_ci reg = (interp_reso << 28) | phase_mult; 81762306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE); 81862306a36Sopenharmony_ci} 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_cistatic void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line) 82162306a36Sopenharmony_ci{ 82262306a36Sopenharmony_ci u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat; 82362306a36Sopenharmony_ci u32 reg; 82462306a36Sopenharmony_ci u16 first, last; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci first = line->crop.left; 82762306a36Sopenharmony_ci last = line->crop.left + line->crop.width - 1; 82862306a36Sopenharmony_ci reg = (first << 16) | last; 82962306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH); 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci first = line->crop.top; 83262306a36Sopenharmony_ci last = line->crop.top + line->crop.height - 1; 83362306a36Sopenharmony_ci reg = (first << 16) | last; 83462306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci first = line->crop.left / 2; 83762306a36Sopenharmony_ci last = line->crop.left / 2 + line->crop.width / 2 - 1; 83862306a36Sopenharmony_ci reg = (first << 16) | last; 83962306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci first = line->crop.top; 84262306a36Sopenharmony_ci last = line->crop.top + line->crop.height - 1; 84362306a36Sopenharmony_ci if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) { 84462306a36Sopenharmony_ci first = line->crop.top / 2; 84562306a36Sopenharmony_ci last = line->crop.top / 2 + line->crop.height / 2 - 1; 84662306a36Sopenharmony_ci } 84762306a36Sopenharmony_ci reg = (first << 16) | last; 84862306a36Sopenharmony_ci writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT); 84962306a36Sopenharmony_ci} 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_cistatic void vfe_set_clamp_cfg(struct vfe_device *vfe) 85262306a36Sopenharmony_ci{ 85362306a36Sopenharmony_ci u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 | 85462306a36Sopenharmony_ci VFE_0_CLAMP_ENC_MAX_CFG_CH1 | 85562306a36Sopenharmony_ci VFE_0_CLAMP_ENC_MAX_CFG_CH2; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 | 86062306a36Sopenharmony_ci VFE_0_CLAMP_ENC_MIN_CFG_CH1 | 86162306a36Sopenharmony_ci VFE_0_CLAMP_ENC_MIN_CFG_CH2; 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG); 86462306a36Sopenharmony_ci} 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_cistatic void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable) 86762306a36Sopenharmony_ci{ 86862306a36Sopenharmony_ci /* empty */ 86962306a36Sopenharmony_ci} 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_cistatic void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line) 87262306a36Sopenharmony_ci{ 87362306a36Sopenharmony_ci u32 val; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci switch (line->fmt[MSM_VFE_PAD_SINK].code) { 87662306a36Sopenharmony_ci case MEDIA_BUS_FMT_YUYV8_2X8: 87762306a36Sopenharmony_ci val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR; 87862306a36Sopenharmony_ci break; 87962306a36Sopenharmony_ci case MEDIA_BUS_FMT_YVYU8_2X8: 88062306a36Sopenharmony_ci val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB; 88162306a36Sopenharmony_ci break; 88262306a36Sopenharmony_ci case MEDIA_BUS_FMT_UYVY8_2X8: 88362306a36Sopenharmony_ci default: 88462306a36Sopenharmony_ci val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY; 88562306a36Sopenharmony_ci break; 88662306a36Sopenharmony_ci case MEDIA_BUS_FMT_VYUY8_2X8: 88762306a36Sopenharmony_ci val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY; 88862306a36Sopenharmony_ci break; 88962306a36Sopenharmony_ci } 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN; 89262306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CORE_CFG); 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; 89562306a36Sopenharmony_ci val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16; 89662306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG); 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1; 89962306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG); 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci val = line->fmt[MSM_VFE_PAD_SINK].height - 1; 90262306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG); 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci val = 0xffffffff; 90562306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG); 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci val = 0xffffffff; 90862306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN); 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci val = 0xffffffff; 91162306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN); 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci val = VFE_0_RDI_CFG_x_MIPI_EN_BITS; 91462306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val); 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN; 91762306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG); 91862306a36Sopenharmony_ci} 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_cistatic void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable) 92162306a36Sopenharmony_ci{ 92262306a36Sopenharmony_ci u32 cmd; 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE; 92562306a36Sopenharmony_ci writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci /* Make sure camif command is issued written before it is changed again */ 92862306a36Sopenharmony_ci wmb(); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci if (enable) 93162306a36Sopenharmony_ci cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY; 93262306a36Sopenharmony_ci else 93362306a36Sopenharmony_ci cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD); 93662306a36Sopenharmony_ci} 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_cistatic void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable) 93962306a36Sopenharmony_ci{ 94062306a36Sopenharmony_ci u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX | 94162306a36Sopenharmony_ci VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE; 94262306a36Sopenharmony_ci u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC | 94362306a36Sopenharmony_ci VFE_0_MODULE_ZOOM_EN_CROP_ENC; 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci if (enable) { 94662306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens); 94762306a36Sopenharmony_ci vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); 94862306a36Sopenharmony_ci } else { 94962306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens); 95062306a36Sopenharmony_ci vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom); 95162306a36Sopenharmony_ci } 95262306a36Sopenharmony_ci} 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_cistatic int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev) 95562306a36Sopenharmony_ci{ 95662306a36Sopenharmony_ci u32 val; 95762306a36Sopenharmony_ci int ret; 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS, 96062306a36Sopenharmony_ci val, 96162306a36Sopenharmony_ci (val & VFE_0_CAMIF_STATUS_HALT), 96262306a36Sopenharmony_ci CAMIF_TIMEOUT_SLEEP_US, 96362306a36Sopenharmony_ci CAMIF_TIMEOUT_ALL_US); 96462306a36Sopenharmony_ci if (ret < 0) 96562306a36Sopenharmony_ci dev_err(dev, "%s: camif stop timeout\n", __func__); 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci return ret; 96862306a36Sopenharmony_ci} 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci/* 97162306a36Sopenharmony_ci * vfe_isr - VFE module interrupt handler 97262306a36Sopenharmony_ci * @irq: Interrupt line 97362306a36Sopenharmony_ci * @dev: VFE device 97462306a36Sopenharmony_ci * 97562306a36Sopenharmony_ci * Return IRQ_HANDLED on success 97662306a36Sopenharmony_ci */ 97762306a36Sopenharmony_cistatic irqreturn_t vfe_isr(int irq, void *dev) 97862306a36Sopenharmony_ci{ 97962306a36Sopenharmony_ci struct vfe_device *vfe = dev; 98062306a36Sopenharmony_ci u32 value0, value1; 98162306a36Sopenharmony_ci int i, j; 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci vfe->ops->isr_read(vfe, &value0, &value1); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n", 98662306a36Sopenharmony_ci value0, value1); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK) 98962306a36Sopenharmony_ci vfe->isr_ops.reset_ack(vfe); 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION) 99262306a36Sopenharmony_ci vfe->ops->violation_read(vfe); 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK) 99562306a36Sopenharmony_ci vfe->isr_ops.halt_ack(vfe); 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) 99862306a36Sopenharmony_ci if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i)) 99962306a36Sopenharmony_ci vfe->isr_ops.reg_update(vfe, i); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF) 100262306a36Sopenharmony_ci vfe->isr_ops.sof(vfe, VFE_LINE_PIX); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++) 100562306a36Sopenharmony_ci if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i)) 100662306a36Sopenharmony_ci vfe->isr_ops.sof(vfe, i); 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++) 100962306a36Sopenharmony_ci if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) { 101062306a36Sopenharmony_ci vfe->isr_ops.comp_done(vfe, i); 101162306a36Sopenharmony_ci for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++) 101262306a36Sopenharmony_ci if (vfe->wm_output_map[j] == VFE_LINE_PIX) 101362306a36Sopenharmony_ci value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j); 101462306a36Sopenharmony_ci } 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++) 101762306a36Sopenharmony_ci if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i)) 101862306a36Sopenharmony_ci vfe->isr_ops.wm_done(vfe, i); 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci return IRQ_HANDLED; 102162306a36Sopenharmony_ci} 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_cistatic u16 vfe_get_ub_size(u8 vfe_id) 102462306a36Sopenharmony_ci{ 102562306a36Sopenharmony_ci /* On VFE4.8 the ub-size is the same on both instances */ 102662306a36Sopenharmony_ci return MSM_VFE_VFE0_UB_SIZE_RDI; 102762306a36Sopenharmony_ci} 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_cistatic void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable) 103062306a36Sopenharmony_ci{ 103162306a36Sopenharmony_ci if (enable) 103262306a36Sopenharmony_ci writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), 103362306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); 103462306a36Sopenharmony_ci else 103562306a36Sopenharmony_ci writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm), 103662306a36Sopenharmony_ci vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD); 103762306a36Sopenharmony_ci 103862306a36Sopenharmony_ci /* The WM must be enabled before sending other commands */ 103962306a36Sopenharmony_ci wmb(); 104062306a36Sopenharmony_ci} 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_cistatic void vfe_set_qos(struct vfe_device *vfe) 104362306a36Sopenharmony_ci{ 104462306a36Sopenharmony_ci u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; 104562306a36Sopenharmony_ci u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG; 104662306a36Sopenharmony_ci u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG; 104762306a36Sopenharmony_ci u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); 105062306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); 105162306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2); 105262306a36Sopenharmony_ci writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3); 105362306a36Sopenharmony_ci writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4); 105462306a36Sopenharmony_ci writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); 105562306a36Sopenharmony_ci writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); 105662306a36Sopenharmony_ci writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); 105762306a36Sopenharmony_ci} 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_cistatic void vfe_set_ds(struct vfe_device *vfe) 106062306a36Sopenharmony_ci{ 106162306a36Sopenharmony_ci u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG; 106262306a36Sopenharmony_ci u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0); 106562306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1); 106662306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2); 106762306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3); 106862306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4); 106962306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5); 107062306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6); 107162306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7); 107262306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8); 107362306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9); 107462306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10); 107562306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11); 107662306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12); 107762306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13); 107862306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14); 107962306a36Sopenharmony_ci writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15); 108062306a36Sopenharmony_ci writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16); 108162306a36Sopenharmony_ci} 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_cistatic void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1) 108462306a36Sopenharmony_ci{ 108562306a36Sopenharmony_ci *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0); 108662306a36Sopenharmony_ci *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1); 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0); 108962306a36Sopenharmony_ci writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1); 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci /* Enforce barrier between local & global IRQ clear */ 109262306a36Sopenharmony_ci wmb(); 109362306a36Sopenharmony_ci writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD); 109462306a36Sopenharmony_ci} 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci/* 109762306a36Sopenharmony_ci * vfe_pm_domain_off - Disable power domains specific to this VFE. 109862306a36Sopenharmony_ci * @vfe: VFE Device 109962306a36Sopenharmony_ci */ 110062306a36Sopenharmony_cistatic void vfe_pm_domain_off(struct vfe_device *vfe) 110162306a36Sopenharmony_ci{ 110262306a36Sopenharmony_ci struct camss *camss = vfe->camss; 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci device_link_del(camss->genpd_link[vfe->id]); 110562306a36Sopenharmony_ci} 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci/* 110862306a36Sopenharmony_ci * vfe_pm_domain_on - Enable power domains specific to this VFE. 110962306a36Sopenharmony_ci * @vfe: VFE Device 111062306a36Sopenharmony_ci */ 111162306a36Sopenharmony_cistatic int vfe_pm_domain_on(struct vfe_device *vfe) 111262306a36Sopenharmony_ci{ 111362306a36Sopenharmony_ci struct camss *camss = vfe->camss; 111462306a36Sopenharmony_ci enum vfe_line_id id = vfe->id; 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS | 111762306a36Sopenharmony_ci DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci if (!camss->genpd_link[id]) { 112062306a36Sopenharmony_ci dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id); 112162306a36Sopenharmony_ci return -EINVAL; 112262306a36Sopenharmony_ci } 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci return 0; 112562306a36Sopenharmony_ci} 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_cistatic void vfe_violation_read(struct vfe_device *vfe) 112862306a36Sopenharmony_ci{ 112962306a36Sopenharmony_ci u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS); 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_ci pr_err_ratelimited("VFE: violation = 0x%08x\n", violation); 113262306a36Sopenharmony_ci} 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_cistatic const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = { 113562306a36Sopenharmony_ci .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi, 113662306a36Sopenharmony_ci .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi, 113762306a36Sopenharmony_ci .bus_enable_wr_if = vfe_bus_enable_wr_if, 113862306a36Sopenharmony_ci .bus_reload_wm = vfe_bus_reload_wm, 113962306a36Sopenharmony_ci .camif_wait_for_stop = vfe_camif_wait_for_stop, 114062306a36Sopenharmony_ci .enable_irq_common = vfe_enable_irq_common, 114162306a36Sopenharmony_ci .enable_irq_pix_line = vfe_enable_irq_pix_line, 114262306a36Sopenharmony_ci .enable_irq_wm_line = vfe_enable_irq_wm_line, 114362306a36Sopenharmony_ci .get_ub_size = vfe_get_ub_size, 114462306a36Sopenharmony_ci .halt_clear = vfe_halt_clear, 114562306a36Sopenharmony_ci .halt_request = vfe_halt_request, 114662306a36Sopenharmony_ci .set_camif_cfg = vfe_set_camif_cfg, 114762306a36Sopenharmony_ci .set_camif_cmd = vfe_set_camif_cmd, 114862306a36Sopenharmony_ci .set_cgc_override = vfe_set_cgc_override, 114962306a36Sopenharmony_ci .set_clamp_cfg = vfe_set_clamp_cfg, 115062306a36Sopenharmony_ci .set_crop_cfg = vfe_set_crop_cfg, 115162306a36Sopenharmony_ci .set_demux_cfg = vfe_set_demux_cfg, 115262306a36Sopenharmony_ci .set_ds = vfe_set_ds, 115362306a36Sopenharmony_ci .set_module_cfg = vfe_set_module_cfg, 115462306a36Sopenharmony_ci .set_qos = vfe_set_qos, 115562306a36Sopenharmony_ci .set_rdi_cid = vfe_set_rdi_cid, 115662306a36Sopenharmony_ci .set_realign_cfg = vfe_set_realign_cfg, 115762306a36Sopenharmony_ci .set_scale_cfg = vfe_set_scale_cfg, 115862306a36Sopenharmony_ci .set_xbar_cfg = vfe_set_xbar_cfg, 115962306a36Sopenharmony_ci .wm_enable = vfe_wm_enable, 116062306a36Sopenharmony_ci .wm_frame_based = vfe_wm_frame_based, 116162306a36Sopenharmony_ci .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status, 116262306a36Sopenharmony_ci .wm_line_based = vfe_wm_line_based, 116362306a36Sopenharmony_ci .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern, 116462306a36Sopenharmony_ci .wm_set_framedrop_period = vfe_wm_set_framedrop_period, 116562306a36Sopenharmony_ci .wm_set_ping_addr = vfe_wm_set_ping_addr, 116662306a36Sopenharmony_ci .wm_set_pong_addr = vfe_wm_set_pong_addr, 116762306a36Sopenharmony_ci .wm_set_subsample = vfe_wm_set_subsample, 116862306a36Sopenharmony_ci .wm_set_ub_cfg = vfe_wm_set_ub_cfg, 116962306a36Sopenharmony_ci}; 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_cistatic void vfe_subdev_init(struct device *dev, struct vfe_device *vfe) 117262306a36Sopenharmony_ci{ 117362306a36Sopenharmony_ci vfe->isr_ops = vfe_isr_ops_gen1; 117462306a36Sopenharmony_ci vfe->ops_gen1 = &vfe_ops_gen1_4_8; 117562306a36Sopenharmony_ci vfe->video_ops = vfe_video_ops_gen1; 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci vfe->line_num = VFE_LINE_NUM_GEN1; 117862306a36Sopenharmony_ci} 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ciconst struct vfe_hw_ops vfe_ops_4_8 = { 118162306a36Sopenharmony_ci .global_reset = vfe_global_reset, 118262306a36Sopenharmony_ci .hw_version = vfe_hw_version, 118362306a36Sopenharmony_ci .isr_read = vfe_isr_read, 118462306a36Sopenharmony_ci .isr = vfe_isr, 118562306a36Sopenharmony_ci .pm_domain_off = vfe_pm_domain_off, 118662306a36Sopenharmony_ci .pm_domain_on = vfe_pm_domain_on, 118762306a36Sopenharmony_ci .reg_update_clear = vfe_reg_update_clear, 118862306a36Sopenharmony_ci .reg_update = vfe_reg_update, 118962306a36Sopenharmony_ci .subdev_init = vfe_subdev_init, 119062306a36Sopenharmony_ci .vfe_disable = vfe_gen1_disable, 119162306a36Sopenharmony_ci .vfe_enable = vfe_gen1_enable, 119262306a36Sopenharmony_ci .vfe_halt = vfe_gen1_halt, 119362306a36Sopenharmony_ci .violation_read = vfe_violation_read, 119462306a36Sopenharmony_ci}; 1195