File Index
Files and directories
Sign in
FILE

camss-vfe-4-1.c

File preview with syntax highlighting.

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