brintos

brintos / linux-shallow public Read only

0
0
Text · 35.7 KiB · ce07191 Raw
1172 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * camss-vfe-4-7.c4 *5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.76 *7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.8 * Copyright (C) 2015-2018 Linaro Ltd.9 */10 11#include <linux/device.h>12#include <linux/interrupt.h>13#include <linux/io.h>14#include <linux/iopoll.h>15 16#include "camss.h"17#include "camss-vfe.h"18#include "camss-vfe-gen1.h"19 20 21#define VFE_0_HW_VERSION		0x00022 23#define VFE_0_GLOBAL_RESET_CMD		0x01824#define VFE_0_GLOBAL_RESET_CMD_CORE	BIT(0)25#define VFE_0_GLOBAL_RESET_CMD_CAMIF	BIT(1)26#define VFE_0_GLOBAL_RESET_CMD_BUS	BIT(2)27#define VFE_0_GLOBAL_RESET_CMD_BUS_BDG	BIT(3)28#define VFE_0_GLOBAL_RESET_CMD_REGISTER	BIT(4)29#define VFE_0_GLOBAL_RESET_CMD_PM	BIT(5)30#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR	BIT(6)31#define VFE_0_GLOBAL_RESET_CMD_TESTGEN	BIT(7)32#define VFE_0_GLOBAL_RESET_CMD_DSP	BIT(8)33#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	BIT(9)34 35#define VFE_0_MODULE_LENS_EN		0x04036#define VFE_0_MODULE_LENS_EN_DEMUX		BIT(2)37#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE	BIT(3)38 39#define VFE_0_MODULE_ZOOM_EN		0x04c40#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC		BIT(1)41#define VFE_0_MODULE_ZOOM_EN_CROP_ENC		BIT(2)42#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF	BIT(9)43 44#define VFE_0_CORE_CFG			0x05045#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR	0x446#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB	0x547#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY	0x648#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY	0x749#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN	BIT(4)50 51#define VFE_0_IRQ_CMD			0x05852#define VFE_0_IRQ_CMD_GLOBAL_CLEAR	BIT(0)53 54#define VFE_0_IRQ_MASK_0		0x05c55#define VFE_0_IRQ_MASK_0_CAMIF_SOF			BIT(0)56#define VFE_0_IRQ_MASK_0_CAMIF_EOF			BIT(1)57#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)58#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)		\59	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))60#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)61#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)62#define VFE_0_IRQ_MASK_0_RESET_ACK			BIT(31)63#define VFE_0_IRQ_MASK_1		0x06064#define VFE_0_IRQ_MASK_1_CAMIF_ERROR			BIT(0)65#define VFE_0_IRQ_MASK_1_VIOLATION			BIT(7)66#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK		BIT(8)67#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)	BIT((n) + 9)68#define VFE_0_IRQ_MASK_1_RDIn_SOF(n)			BIT((n) + 29)69 70#define VFE_0_IRQ_CLEAR_0		0x06471#define VFE_0_IRQ_CLEAR_1		0x06872 73#define VFE_0_IRQ_STATUS_0		0x06c74#define VFE_0_IRQ_STATUS_0_CAMIF_SOF			BIT(0)75#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)		BIT((n) + 5)76#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)		\77	((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))78#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)79#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)80#define VFE_0_IRQ_STATUS_0_RESET_ACK			BIT(31)81#define VFE_0_IRQ_STATUS_1		0x07082#define VFE_0_IRQ_STATUS_1_VIOLATION			BIT(7)83#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK		BIT(8)84#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)			BIT((n) + 29)85 86#define VFE_0_IRQ_COMPOSITE_MASK_0	0x07487#define VFE_0_VIOLATION_STATUS		0x07c88 89#define VFE_0_BUS_CMD			0x8090#define VFE_0_BUS_CMD_Mx_RLD_CMD(x)	BIT(x)91 92#define VFE_0_BUS_CFG			0x08493 94#define VFE_0_BUS_XBAR_CFG_x(x)		(0x90 + 0x4 * ((x) / 2))95#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN			BIT(2)96#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN			BIT(3)97#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA		(0x1 << 4)98#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER		(0x2 << 4)99#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA	(0x3 << 4)100#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT		8101#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA		0x0102#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0	0xc103#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1	0xd104#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2	0xe105 106#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)		(0x0a0 + 0x2c * (n))107#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT	0108#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)	(0x0a4 + 0x2c * (n))109#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)	(0x0ac + 0x2c * (n))110#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)		(0x0b4 + 0x2c * (n))111#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT	1112#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT	2113#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK	(0x1f << 2)114#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)		(0x0b8 + 0x2c * (n))115#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT	16116#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)	(0x0bc + 0x2c * (n))117#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)	(0x0c0 + 0x2c * (n))118#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)	\119							(0x0c4 + 0x2c * (n))120#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)	\121							(0x0c8 + 0x2c * (n))122#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF	0xffffffff123 124#define VFE_0_BUS_PING_PONG_STATUS	0x338125 126#define VFE_0_BUS_BDG_CMD		0x400127#define VFE_0_BUS_BDG_CMD_HALT_REQ	1128 129#define VFE_0_BUS_BDG_QOS_CFG_0		0x404130#define VFE_0_BUS_BDG_QOS_CFG_0_CFG	0xaaa9aaa9131#define VFE_0_BUS_BDG_QOS_CFG_1		0x408132#define VFE_0_BUS_BDG_QOS_CFG_2		0x40c133#define VFE_0_BUS_BDG_QOS_CFG_3		0x410134#define VFE_0_BUS_BDG_QOS_CFG_4		0x414135#define VFE_0_BUS_BDG_QOS_CFG_5		0x418136#define VFE_0_BUS_BDG_QOS_CFG_6		0x41c137#define VFE_0_BUS_BDG_QOS_CFG_7		0x420138#define VFE_0_BUS_BDG_QOS_CFG_7_CFG	0x0001aaa9139 140#define VFE48_0_BUS_BDG_QOS_CFG_0_CFG	0xaaa5aaa5141#define VFE48_0_BUS_BDG_QOS_CFG_3_CFG	0xaa55aaa5142#define VFE48_0_BUS_BDG_QOS_CFG_4_CFG	0xaa55aa55143#define VFE48_0_BUS_BDG_QOS_CFG_7_CFG	0x0005aa55144 145#define VFE_0_BUS_BDG_DS_CFG_0		0x424146#define VFE_0_BUS_BDG_DS_CFG_0_CFG	0xcccc0011147#define VFE_0_BUS_BDG_DS_CFG_1		0x428148#define VFE_0_BUS_BDG_DS_CFG_2		0x42c149#define VFE_0_BUS_BDG_DS_CFG_3		0x430150#define VFE_0_BUS_BDG_DS_CFG_4		0x434151#define VFE_0_BUS_BDG_DS_CFG_5		0x438152#define VFE_0_BUS_BDG_DS_CFG_6		0x43c153#define VFE_0_BUS_BDG_DS_CFG_7		0x440154#define VFE_0_BUS_BDG_DS_CFG_8		0x444155#define VFE_0_BUS_BDG_DS_CFG_9		0x448156#define VFE_0_BUS_BDG_DS_CFG_10		0x44c157#define VFE_0_BUS_BDG_DS_CFG_11		0x450158#define VFE_0_BUS_BDG_DS_CFG_12		0x454159#define VFE_0_BUS_BDG_DS_CFG_13		0x458160#define VFE_0_BUS_BDG_DS_CFG_14		0x45c161#define VFE_0_BUS_BDG_DS_CFG_15		0x460162#define VFE_0_BUS_BDG_DS_CFG_16		0x464163#define VFE_0_BUS_BDG_DS_CFG_16_CFG	0x40000103164 165#define VFE48_0_BUS_BDG_DS_CFG_0_CFG	0xcccc1111166#define VFE48_0_BUS_BDG_DS_CFG_16_CFG	0x00000110167 168#define VFE_0_RDI_CFG_x(x)		(0x46c + (0x4 * (x)))169#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT	28170#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK	(0xf << 28)171#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT	4172#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK		(0xf << 4)173#define VFE_0_RDI_CFG_x_RDI_EN_BIT		BIT(2)174#define VFE_0_RDI_CFG_x_MIPI_EN_BITS		0x3175 176#define VFE_0_CAMIF_CMD				0x478177#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY	0178#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY	1179#define VFE_0_CAMIF_CMD_NO_CHANGE		3180#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS	BIT(2)181#define VFE_0_CAMIF_CFG				0x47c182#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN		BIT(6)183#define VFE_0_CAMIF_FRAME_CFG			0x484184#define VFE_0_CAMIF_WINDOW_WIDTH_CFG		0x488185#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG		0x48c186#define VFE_0_CAMIF_SUBSAMPLE_CFG		0x490187#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN	0x498188#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN	0x49c189#define VFE_0_CAMIF_STATUS			0x4a4190#define VFE_0_CAMIF_STATUS_HALT			BIT(31)191 192#define VFE_0_REG_UPDATE		0x4ac193#define VFE_0_REG_UPDATE_RDIn(n)		BIT(1 + (n))194#define VFE_0_REG_UPDATE_line_n(n)		\195			((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))196 197#define VFE_0_DEMUX_CFG				0x560198#define VFE_0_DEMUX_CFG_PERIOD			0x3199#define VFE_0_DEMUX_GAIN_0			0x564200#define VFE_0_DEMUX_GAIN_0_CH0_EVEN		(0x80 << 0)201#define VFE_0_DEMUX_GAIN_0_CH0_ODD		(0x80 << 16)202#define VFE_0_DEMUX_GAIN_1			0x568203#define VFE_0_DEMUX_GAIN_1_CH1			(0x80 << 0)204#define VFE_0_DEMUX_GAIN_1_CH2			(0x80 << 16)205#define VFE_0_DEMUX_EVEN_CFG			0x574206#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV	0x9cac207#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU	0xac9c208#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY	0xc9ca209#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY	0xcac9210#define VFE_0_DEMUX_ODD_CFG			0x578211#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV	0x9cac212#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU	0xac9c213#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY	0xc9ca214#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY	0xcac9215 216#define VFE_0_SCALE_ENC_Y_CFG			0x91c217#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE		0x920218#define VFE_0_SCALE_ENC_Y_H_PHASE		0x924219#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE		0x934220#define VFE_0_SCALE_ENC_Y_V_PHASE		0x938221#define VFE_0_SCALE_ENC_CBCR_CFG		0x948222#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE	0x94c223#define VFE_0_SCALE_ENC_CBCR_H_PHASE		0x950224#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE	0x960225#define VFE_0_SCALE_ENC_CBCR_V_PHASE		0x964226 227#define VFE_0_CROP_ENC_Y_WIDTH			0x974228#define VFE_0_CROP_ENC_Y_HEIGHT			0x978229#define VFE_0_CROP_ENC_CBCR_WIDTH		0x97c230#define VFE_0_CROP_ENC_CBCR_HEIGHT		0x980231 232#define VFE_0_CLAMP_ENC_MAX_CFG			0x984233#define VFE_0_CLAMP_ENC_MAX_CFG_CH0		(0xff << 0)234#define VFE_0_CLAMP_ENC_MAX_CFG_CH1		(0xff << 8)235#define VFE_0_CLAMP_ENC_MAX_CFG_CH2		(0xff << 16)236#define VFE_0_CLAMP_ENC_MIN_CFG			0x988237#define VFE_0_CLAMP_ENC_MIN_CFG_CH0		(0x0 << 0)238#define VFE_0_CLAMP_ENC_MIN_CFG_CH1		(0x0 << 8)239#define VFE_0_CLAMP_ENC_MIN_CFG_CH2		(0x0 << 16)240 241#define VFE_0_REALIGN_BUF_CFG			0xaac242#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL     BIT(2)243#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL     BIT(3)244#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE      BIT(4)245 246#define VFE48_0_BUS_IMAGE_MASTER_CMD		0xcec247#define VFE48_0_BUS_IMAGE_MASTER_n_SHIFT(x)	(2 * (x))248 249#define CAMIF_TIMEOUT_SLEEP_US 1000250#define CAMIF_TIMEOUT_ALL_US 1000000251 252#define MSM_VFE_VFE0_UB_SIZE 2047253#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)254#define MSM_VFE_VFE1_UB_SIZE 1535255#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3)256 257static u32 vfe_hw_version(struct vfe_device *vfe)258{259	u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);260 261	dev_dbg(vfe->camss->dev, "VFE HW Version = 0x%08x\n", hw_version);262 263	return hw_version;264}265 266static u16 vfe_get_ub_size(u8 vfe_id)267{268	if (vfe_id == 0)269		return MSM_VFE_VFE0_UB_SIZE_RDI;270	else if (vfe_id == 1)271		return MSM_VFE_VFE1_UB_SIZE_RDI;272 273	return 0;274}275 276static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)277{278	u32 bits = readl_relaxed(vfe->base + reg);279 280	writel_relaxed(bits & ~clr_bits, vfe->base + reg);281}282 283static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)284{285	u32 bits = readl_relaxed(vfe->base + reg);286 287	writel_relaxed(bits | set_bits, vfe->base + reg);288}289 290static void vfe_global_reset(struct vfe_device *vfe)291{292	u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC	|293			 VFE_0_GLOBAL_RESET_CMD_DSP		|294			 VFE_0_GLOBAL_RESET_CMD_TESTGEN		|295			 VFE_0_GLOBAL_RESET_CMD_BUS_MISR	|296			 VFE_0_GLOBAL_RESET_CMD_PM		|297			 VFE_0_GLOBAL_RESET_CMD_REGISTER	|298			 VFE_0_GLOBAL_RESET_CMD_BUS_BDG		|299			 VFE_0_GLOBAL_RESET_CMD_BUS		|300			 VFE_0_GLOBAL_RESET_CMD_CAMIF		|301			 VFE_0_GLOBAL_RESET_CMD_CORE;302 303	writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0);304 305	/* Enforce barrier between IRQ mask setup and global reset */306	wmb();307	writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);308}309 310static void vfe_halt_request(struct vfe_device *vfe)311{312	writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,313		       vfe->base + VFE_0_BUS_BDG_CMD);314}315 316static void vfe_halt_clear(struct vfe_device *vfe)317{318	writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);319}320 321static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)322{323	if (enable)324		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),325			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);326	else327		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(wm),328			    1 << VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT);329}330 331static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)332{333	if (enable)334		vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),335			1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);336	else337		vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),338			1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);339}340 341#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))342 343static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line)344{345	int val = 0;346 347	switch (format) {348	case V4L2_PIX_FMT_NV12:349	case V4L2_PIX_FMT_NV21:350	case V4L2_PIX_FMT_NV16:351	case V4L2_PIX_FMT_NV61:352		val = CALC_WORD(pixel_per_line, 1, 8);353		break;354	case V4L2_PIX_FMT_YUYV:355	case V4L2_PIX_FMT_YVYU:356	case V4L2_PIX_FMT_UYVY:357	case V4L2_PIX_FMT_VYUY:358		val = CALC_WORD(pixel_per_line, 2, 8);359		break;360	}361 362	return val;363}364 365static int vfe_word_per_line_by_bytes(u32 bytes_per_line)366{367	return CALC_WORD(bytes_per_line, 1, 8);368}369 370static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,371			     u16 *width, u16 *height, u16 *bytesperline)372{373	*width = pix->width;374	*height = pix->height;375 376	switch (pix->pixelformat) {377	case V4L2_PIX_FMT_NV12:378	case V4L2_PIX_FMT_NV21:379		*bytesperline = pix->plane_fmt[0].bytesperline;380		if (plane == 1)381			*height /= 2;382		break;383	case V4L2_PIX_FMT_NV16:384	case V4L2_PIX_FMT_NV61:385		*bytesperline = pix->plane_fmt[0].bytesperline;386		break;387	case V4L2_PIX_FMT_YUYV:388	case V4L2_PIX_FMT_YVYU:389	case V4L2_PIX_FMT_VYUY:390	case V4L2_PIX_FMT_UYVY:391		*bytesperline = pix->plane_fmt[plane].bytesperline;392		break;393	}394}395 396static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,397			      struct v4l2_pix_format_mplane *pix,398			      u8 plane, u32 enable)399{400	u32 reg;401 402	if (enable) {403		u16 width = 0, height = 0, bytesperline = 0, wpl;404 405		vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);406 407		wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width);408 409		reg = height - 1;410		reg |= ((wpl + 3) / 4 - 1) << 16;411 412		writel_relaxed(reg, vfe->base +413			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));414 415		wpl = vfe_word_per_line_by_bytes(bytesperline);416 417		reg = 0x3;418		reg |= (height - 1) << 2;419		reg |= ((wpl + 1) / 2) << 16;420 421		writel_relaxed(reg, vfe->base +422			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));423	} else {424		writel_relaxed(0, vfe->base +425			       VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));426		writel_relaxed(0, vfe->base +427			       VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));428	}429}430 431static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)432{433	u32 reg;434 435	reg = readl_relaxed(vfe->base +436			    VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));437 438	reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);439 440	reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)441		& VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;442 443	writel_relaxed(reg,444		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));445}446 447static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,448					 u32 pattern)449{450	writel_relaxed(pattern,451	       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));452}453 454static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,455			      u16 offset, u16 depth)456{457	u32 reg;458 459	reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |460		depth;461	writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));462}463 464static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)465{466	/* Enforce barrier between any outstanding register write */467	wmb();468 469	writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);470 471	/* Use barrier to make sure bus reload is issued before anything else */472	wmb();473}474 475static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)476{477	writel_relaxed(addr,478		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));479}480 481static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)482{483	writel_relaxed(addr,484		       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));485}486 487static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)488{489	u32 reg;490 491	reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);492 493	return (reg >> wm) & 0x1;494}495 496static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)497{498	if (enable)499		writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG);500	else501		writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);502}503 504static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,505				      enum vfe_line_id id)506{507	u32 reg;508 509	reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;510	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);511 512	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;513	reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &514		VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;515	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);516 517	switch (id) {518	case VFE_LINE_RDI0:519	default:520		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<521		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;522		break;523	case VFE_LINE_RDI1:524		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<525		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;526		break;527	case VFE_LINE_RDI2:528		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<529		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;530		break;531	}532 533	if (wm % 2 == 1)534		reg <<= 16;535 536	vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);537}538 539static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)540{541	writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,542	       vfe->base +543	       VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));544}545 546static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,547					   enum vfe_line_id id)548{549	u32 reg;550 551	reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;552	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);553 554	switch (id) {555	case VFE_LINE_RDI0:556	default:557		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<558		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;559		break;560	case VFE_LINE_RDI1:561		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<562		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;563		break;564	case VFE_LINE_RDI2:565		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<566		      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;567		break;568	}569 570	if (wm % 2 == 1)571		reg <<= 16;572 573	vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);574}575 576static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,577			     u8 enable)578{579	struct vfe_line *line = container_of(output, struct vfe_line, output);580	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;581	u32 reg;582 583	switch (p) {584	case V4L2_PIX_FMT_NV12:585	case V4L2_PIX_FMT_NV21:586	case V4L2_PIX_FMT_NV16:587	case V4L2_PIX_FMT_NV61:588		reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<589			VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;590 591		if (output->wm_idx[0] % 2 == 1)592			reg <<= 16;593 594		if (enable)595			vfe_reg_set(vfe,596				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),597				    reg);598		else599			vfe_reg_clr(vfe,600				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),601				    reg);602 603		reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;604		if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)605			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;606 607		if (output->wm_idx[1] % 2 == 1)608			reg <<= 16;609 610		if (enable)611			vfe_reg_set(vfe,612				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),613				    reg);614		else615			vfe_reg_clr(vfe,616				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),617				    reg);618		break;619	case V4L2_PIX_FMT_YUYV:620	case V4L2_PIX_FMT_YVYU:621	case V4L2_PIX_FMT_VYUY:622	case V4L2_PIX_FMT_UYVY:623		reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN;624		reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;625 626		if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU)627			reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;628 629		if (output->wm_idx[0] % 2 == 1)630			reg <<= 16;631 632		if (enable)633			vfe_reg_set(vfe,634				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),635				    reg);636		else637			vfe_reg_clr(vfe,638				    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),639				    reg);640		break;641	default:642		break;643	}644}645 646static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,647				u8 enable)648{649	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;650	u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF;651 652	if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU &&653			p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY)654		return;655 656	if (enable) {657		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val);658	} else {659		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val);660		return;661	}662 663	val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE;664 665	if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV)666		val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL;667	else668		val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL;669 670	writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG);671}672 673static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)674{675	vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),676		    VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);677 678	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),679		    cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);680}681 682static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)683{684	vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);685 686	/* Enforce barrier between line update and commit */687	wmb();688	writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);689 690	/* Make sure register update is issued before further reg writes */691	wmb();692}693 694static inline void vfe_reg_update_clear(struct vfe_device *vfe,695					enum vfe_line_id line_id)696{697	vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);698}699 700static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,701				   enum vfe_line_id line_id, u8 enable)702{703	u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |704		      VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);705	u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |706		      VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);707 708	if (enable) {709		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);710		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);711	} else {712		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);713		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);714	}715}716 717static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,718				    enum vfe_line_id line_id, u8 enable)719{720	struct vfe_output *output = &vfe->line[line_id].output;721	unsigned int i;722	u32 irq_en0;723	u32 irq_en1;724	u32 comp_mask = 0;725 726	irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;727	irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;728	irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);729	irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);730	irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;731	for (i = 0; i < output->wm_num; i++) {732		irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(733							output->wm_idx[i]);734		comp_mask |= (1 << output->wm_idx[i]) << comp * 8;735	}736 737	if (enable) {738		vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);739		vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);740		vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);741	} else {742		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);743		vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);744		vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);745	}746}747 748static void vfe_enable_irq_common(struct vfe_device *vfe)749{750	u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;751	u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |752		      VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;753 754	vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);755	vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);756}757 758static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)759{760	u32 val, even_cfg, odd_cfg;761 762	writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);763 764	val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;765	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);766 767	val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;768	writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);769 770	switch (line->fmt[MSM_VFE_PAD_SINK].code) {771	case MEDIA_BUS_FMT_YUYV8_1X16:772		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;773		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;774		break;775	case MEDIA_BUS_FMT_YVYU8_1X16:776		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;777		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;778		break;779	case MEDIA_BUS_FMT_UYVY8_1X16:780	default:781		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;782		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;783		break;784	case MEDIA_BUS_FMT_VYUY8_1X16:785		even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;786		odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;787		break;788	}789 790	writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);791	writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);792}793 794static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)795{796	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;797	u32 reg;798	u16 input, output;799	u8 interp_reso;800	u32 phase_mult;801 802	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);803 804	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;805	output = line->compose.width - 1;806	reg = (output << 16) | input;807	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);808 809	interp_reso = vfe_calc_interp_reso(input, output);810	phase_mult = input * (1 << (14 + interp_reso)) / output;811	reg = (interp_reso << 28) | phase_mult;812	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);813 814	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;815	output = line->compose.height - 1;816	reg = (output << 16) | input;817	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);818 819	interp_reso = vfe_calc_interp_reso(input, output);820	phase_mult = input * (1 << (14 + interp_reso)) / output;821	reg = (interp_reso << 28) | phase_mult;822	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);823 824	writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);825 826	input = line->fmt[MSM_VFE_PAD_SINK].width - 1;827	output = line->compose.width / 2 - 1;828	reg = (output << 16) | input;829	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);830 831	interp_reso = vfe_calc_interp_reso(input, output);832	phase_mult = input * (1 << (14 + interp_reso)) / output;833	reg = (interp_reso << 28) | phase_mult;834	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);835 836	input = line->fmt[MSM_VFE_PAD_SINK].height - 1;837	output = line->compose.height - 1;838	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)839		output = line->compose.height / 2 - 1;840	reg = (output << 16) | input;841	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);842 843	interp_reso = vfe_calc_interp_reso(input, output);844	phase_mult = input * (1 << (14 + interp_reso)) / output;845	reg = (interp_reso << 28) | phase_mult;846	writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);847}848 849static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)850{851	u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;852	u32 reg;853	u16 first, last;854 855	first = line->crop.left;856	last = line->crop.left + line->crop.width - 1;857	reg = (first << 16) | last;858	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);859 860	first = line->crop.top;861	last = line->crop.top + line->crop.height - 1;862	reg = (first << 16) | last;863	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);864 865	first = line->crop.left / 2;866	last = line->crop.left / 2 + line->crop.width / 2 - 1;867	reg = (first << 16) | last;868	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);869 870	first = line->crop.top;871	last = line->crop.top + line->crop.height - 1;872	if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {873		first = line->crop.top / 2;874		last = line->crop.top / 2 + line->crop.height / 2 - 1;875	}876	reg = (first << 16) | last;877	writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);878}879 880static void vfe_set_clamp_cfg(struct vfe_device *vfe)881{882	u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |883		VFE_0_CLAMP_ENC_MAX_CFG_CH1 |884		VFE_0_CLAMP_ENC_MAX_CFG_CH2;885 886	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);887 888	val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |889		VFE_0_CLAMP_ENC_MIN_CFG_CH1 |890		VFE_0_CLAMP_ENC_MIN_CFG_CH2;891 892	writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);893}894 895static void vfe_set_qos(struct vfe_device *vfe)896{897	u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;898	u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;899 900	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);901	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);902	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);903	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);904	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);905	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);906	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);907	writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);908}909 910static void vfe_set_ds(struct vfe_device *vfe)911{912	u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;913	u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;914 915	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);916	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);917	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);918	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);919	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);920	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);921	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);922	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);923	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);924	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);925	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);926	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);927	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);928	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);929	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);930	writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);931	writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);932}933 934static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)935{936	/* empty */937}938 939static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)940{941	u32 val;942 943	switch (line->fmt[MSM_VFE_PAD_SINK].code) {944	case MEDIA_BUS_FMT_YUYV8_1X16:945		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;946		break;947	case MEDIA_BUS_FMT_YVYU8_1X16:948		val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;949		break;950	case MEDIA_BUS_FMT_UYVY8_1X16:951	default:952		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;953		break;954	case MEDIA_BUS_FMT_VYUY8_1X16:955		val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;956		break;957	}958 959	val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN;960	writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);961 962	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;963	val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16;964	writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);965 966	val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;967	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);968 969	val = line->fmt[MSM_VFE_PAD_SINK].height - 1;970	writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);971 972	val = 0xffffffff;973	writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG);974 975	val = 0xffffffff;976	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN);977 978	val = 0xffffffff;979	writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);980 981	val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;982	vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);983 984	val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;985	writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);986}987 988static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)989{990	u32 cmd;991 992	cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;993	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);994 995	/* Make sure camif command is issued written before it is changed again */996	wmb();997 998	if (enable)999		cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;1000	else1001		cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;1002 1003	writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);1004}1005 1006static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)1007{1008	u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX |1009		       VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE;1010	u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC |1011		       VFE_0_MODULE_ZOOM_EN_CROP_ENC;1012 1013	if (enable) {1014		vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens);1015		vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);1016	} else {1017		vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens);1018		vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);1019	}1020}1021 1022static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)1023{1024	u32 val;1025	int ret;1026 1027	ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,1028				 val,1029				 (val & VFE_0_CAMIF_STATUS_HALT),1030				 CAMIF_TIMEOUT_SLEEP_US,1031				 CAMIF_TIMEOUT_ALL_US);1032	if (ret < 0)1033		dev_err(dev, "%s: camif stop timeout\n", __func__);1034 1035	return ret;1036}1037 1038 1039 1040/*1041 * vfe_isr - VFE module interrupt handler1042 * @irq: Interrupt line1043 * @dev: VFE device1044 *1045 * Return IRQ_HANDLED on success1046 */1047static irqreturn_t vfe_isr(int irq, void *dev)1048{1049	struct vfe_device *vfe = dev;1050	u32 value0, value1;1051	int i, j;1052 1053	vfe->res->hw_ops->isr_read(vfe, &value0, &value1);1054 1055	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",1056		value0, value1);1057 1058	if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)1059		vfe->isr_ops.reset_ack(vfe);1060 1061	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)1062		vfe->res->hw_ops->violation_read(vfe);1063 1064	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)1065		vfe->isr_ops.halt_ack(vfe);1066 1067	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)1068		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))1069			vfe->isr_ops.reg_update(vfe, i);1070 1071	if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)1072		vfe->isr_ops.sof(vfe, VFE_LINE_PIX);1073 1074	for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)1075		if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))1076			vfe->isr_ops.sof(vfe, i);1077 1078	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)1079		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {1080			vfe->isr_ops.comp_done(vfe, i);1081			for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)1082				if (vfe->wm_output_map[j] == VFE_LINE_PIX)1083					value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);1084		}1085 1086	for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)1087		if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))1088			vfe->isr_ops.wm_done(vfe, i);1089 1090	return IRQ_HANDLED;1091}1092 1093static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)1094{1095	*value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);1096	*value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);1097 1098	writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);1099	writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);1100 1101	/* Enforce barrier between local & global IRQ clear */1102	wmb();1103	writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);1104}1105 1106static void vfe_violation_read(struct vfe_device *vfe)1107{1108	u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);1109 1110	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);1111}1112 1113static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_7 = {1114	.bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,1115	.bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,1116	.bus_enable_wr_if = vfe_bus_enable_wr_if,1117	.bus_reload_wm = vfe_bus_reload_wm,1118	.camif_wait_for_stop = vfe_camif_wait_for_stop,1119	.enable_irq_common = vfe_enable_irq_common,1120	.enable_irq_pix_line = vfe_enable_irq_pix_line,1121	.enable_irq_wm_line = vfe_enable_irq_wm_line,1122	.get_ub_size = vfe_get_ub_size,1123	.halt_clear = vfe_halt_clear,1124	.halt_request = vfe_halt_request,1125	.set_camif_cfg = vfe_set_camif_cfg,1126	.set_camif_cmd = vfe_set_camif_cmd,1127	.set_cgc_override = vfe_set_cgc_override,1128	.set_clamp_cfg = vfe_set_clamp_cfg,1129	.set_crop_cfg = vfe_set_crop_cfg,1130	.set_demux_cfg = vfe_set_demux_cfg,1131	.set_ds = vfe_set_ds,1132	.set_module_cfg = vfe_set_module_cfg,1133	.set_qos = vfe_set_qos,1134	.set_rdi_cid = vfe_set_rdi_cid,1135	.set_realign_cfg = vfe_set_realign_cfg,1136	.set_scale_cfg = vfe_set_scale_cfg,1137	.set_xbar_cfg = vfe_set_xbar_cfg,1138	.wm_enable = vfe_wm_enable,1139	.wm_frame_based = vfe_wm_frame_based,1140	.wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,1141	.wm_line_based = vfe_wm_line_based,1142	.wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,1143	.wm_set_framedrop_period = vfe_wm_set_framedrop_period,1144	.wm_set_ping_addr = vfe_wm_set_ping_addr,1145	.wm_set_pong_addr = vfe_wm_set_pong_addr,1146	.wm_set_subsample = vfe_wm_set_subsample,1147	.wm_set_ub_cfg = vfe_wm_set_ub_cfg,1148};1149 1150static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)1151{1152	vfe->isr_ops = vfe_isr_ops_gen1;1153	vfe->ops_gen1 = &vfe_ops_gen1_4_7;1154	vfe->video_ops = vfe_video_ops_gen1;1155}1156 1157const struct vfe_hw_ops vfe_ops_4_7 = {1158	.global_reset = vfe_global_reset,1159	.hw_version = vfe_hw_version,1160	.isr_read = vfe_isr_read,1161	.isr = vfe_isr,1162	.pm_domain_off = vfe_pm_domain_off,1163	.pm_domain_on = vfe_pm_domain_on,1164	.reg_update_clear = vfe_reg_update_clear,1165	.reg_update = vfe_reg_update,1166	.subdev_init = vfe_subdev_init,1167	.vfe_disable = vfe_gen1_disable,1168	.vfe_enable = vfe_gen1_enable,1169	.vfe_halt = vfe_gen1_halt,1170	.violation_read = vfe_violation_read,1171};1172