linux/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * camss-vfe-4-8.c
   4 *
   5 * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v4.8
   6 *
   7 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
   8 * Copyright (C) 2015-2021 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#define VFE_0_HW_VERSION                0x000
  21
  22#define VFE_0_GLOBAL_RESET_CMD          0x018
  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_PM       BIT(5)
  29#define VFE_0_GLOBAL_RESET_CMD_BUS_MISR BIT(6)
  30#define VFE_0_GLOBAL_RESET_CMD_TESTGEN  BIT(7)
  31#define VFE_0_GLOBAL_RESET_CMD_DSP      BIT(8)
  32#define VFE_0_GLOBAL_RESET_CMD_IDLE_CGC BIT(9)
  33
  34#define VFE_0_MODULE_LENS_EN            0x040
  35#define VFE_0_MODULE_LENS_EN_DEMUX              BIT(2)
  36#define VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE    BIT(3)
  37
  38#define VFE_0_MODULE_ZOOM_EN            0x04c
  39#define VFE_0_MODULE_ZOOM_EN_SCALE_ENC          BIT(1)
  40#define VFE_0_MODULE_ZOOM_EN_CROP_ENC           BIT(2)
  41#define VFE_0_MODULE_ZOOM_EN_REALIGN_BUF        BIT(9)
  42
  43#define VFE_0_CORE_CFG                  0x050
  44#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR     0x4
  45#define VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB     0x5
  46#define VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY     0x6
  47#define VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY     0x7
  48#define VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN  BIT(4)
  49
  50#define VFE_0_IRQ_CMD                   0x058
  51#define VFE_0_IRQ_CMD_GLOBAL_CLEAR      BIT(0)
  52
  53#define VFE_0_IRQ_MASK_0                0x05c
  54#define VFE_0_IRQ_MASK_0_CAMIF_SOF                      BIT(0)
  55#define VFE_0_IRQ_MASK_0_CAMIF_EOF                      BIT(1)
  56#define VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n)             BIT((n) + 5)
  57#define VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(n)           \
  58        ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_MASK_0_RDIn_REG_UPDATE(n))
  59#define VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(n)    BIT((n) + 8)
  60#define VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(n)      BIT((n) + 25)
  61#define VFE_0_IRQ_MASK_0_RESET_ACK                      BIT(31)
  62#define VFE_0_IRQ_MASK_1                0x060
  63#define VFE_0_IRQ_MASK_1_CAMIF_ERROR                    BIT(0)
  64#define VFE_0_IRQ_MASK_1_VIOLATION                      BIT(7)
  65#define VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK               BIT(8)
  66#define VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n) BIT((n) + 9)
  67#define VFE_0_IRQ_MASK_1_RDIn_SOF(n)                    BIT((n) + 29)
  68
  69#define VFE_0_IRQ_CLEAR_0               0x064
  70#define VFE_0_IRQ_CLEAR_1               0x068
  71
  72#define VFE_0_IRQ_STATUS_0              0x06c
  73#define VFE_0_IRQ_STATUS_0_CAMIF_SOF                    BIT(0)
  74#define VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n)           BIT((n) + 5)
  75#define VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(n)         \
  76        ((n) == VFE_LINE_PIX ? BIT(4) : VFE_0_IRQ_STATUS_0_RDIn_REG_UPDATE(n))
  77#define VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(n)  BIT((n) + 8)
  78#define VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(n)    BIT((n) + 25)
  79#define VFE_0_IRQ_STATUS_0_RESET_ACK                    BIT(31)
  80#define VFE_0_IRQ_STATUS_1              0x070
  81#define VFE_0_IRQ_STATUS_1_VIOLATION                    BIT(7)
  82#define VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK             BIT(8)
  83#define VFE_0_IRQ_STATUS_1_RDIn_SOF(n)                  BIT((n) + 29)
  84
  85#define VFE_0_IRQ_COMPOSITE_MASK_0      0x074
  86#define VFE_0_VIOLATION_STATUS          0x07c
  87
  88#define VFE_0_BUS_CMD                   0x80
  89#define VFE_0_BUS_CMD_Mx_RLD_CMD(x)     BIT(x)
  90
  91#define VFE_0_BUS_CFG                   0x084
  92
  93#define VFE_0_BUS_XBAR_CFG_x(x)         (0x90 + 0x4 * ((x) / 2))
  94#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN                   BIT(2)
  95#define VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN                   BIT(3)
  96#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTRA           (0x1 << 4)
  97#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER           (0x2 << 4)
  98#define VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA     (0x3 << 4)
  99#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT          8
 100#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA           0x0
 101#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0       0xc
 102#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1       0xd
 103#define VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2       0xe
 104
 105#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG(n)              (0x0a0 + 0x2c * (n))
 106#define VFE_0_BUS_IMAGE_MASTER_n_WR_CFG_WR_PATH_SHIFT   0
 107#define VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(n)        (0x0a4 + 0x2c * (n))
 108#define VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(n)        (0x0ac + 0x2c * (n))
 109#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(n)         (0x0b4 + 0x2c * (n))
 110#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT    1
 111#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT 2
 112#define VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK  (0x1f << 2)
 113#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(n)           (0x0b8 + 0x2c * (n))
 114#define VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT 16
 115#define VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(n)       (0x0bc + 0x2c * (n))
 116#define VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(n)       (0x0c0 + 0x2c * (n))
 117#define VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(n)        \
 118                                                        (0x0c4 + 0x2c * (n))
 119#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(n)    \
 120                                                        (0x0c8 + 0x2c * (n))
 121#define VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF   0xffffffff
 122
 123#define VFE_0_BUS_PING_PONG_STATUS      0x338
 124
 125#define VFE_0_BUS_BDG_CMD               0x400
 126#define VFE_0_BUS_BDG_CMD_HALT_REQ      1
 127
 128#define VFE_0_BUS_BDG_QOS_CFG_0         0x404
 129#define VFE_0_BUS_BDG_QOS_CFG_0_CFG     0xaaa5aaa5
 130#define VFE_0_BUS_BDG_QOS_CFG_1         0x408
 131#define VFE_0_BUS_BDG_QOS_CFG_2         0x40c
 132#define VFE_0_BUS_BDG_QOS_CFG_3         0x410
 133#define VFE_0_BUS_BDG_QOS_CFG_3_CFG     0xaa55aaa5
 134#define VFE_0_BUS_BDG_QOS_CFG_4         0x414
 135#define VFE_0_BUS_BDG_QOS_CFG_4_CFG     0xaa55aa55
 136#define VFE_0_BUS_BDG_QOS_CFG_5         0x418
 137#define VFE_0_BUS_BDG_QOS_CFG_6         0x41c
 138#define VFE_0_BUS_BDG_QOS_CFG_7         0x420
 139#define VFE_0_BUS_BDG_QOS_CFG_7_CFG     0x0005aa55
 140
 141#define VFE_0_BUS_BDG_DS_CFG_0          0x424
 142#define VFE_0_BUS_BDG_DS_CFG_0_CFG      0xcccc1111
 143#define VFE_0_BUS_BDG_DS_CFG_1          0x428
 144#define VFE_0_BUS_BDG_DS_CFG_2          0x42c
 145#define VFE_0_BUS_BDG_DS_CFG_3          0x430
 146#define VFE_0_BUS_BDG_DS_CFG_4          0x434
 147#define VFE_0_BUS_BDG_DS_CFG_5          0x438
 148#define VFE_0_BUS_BDG_DS_CFG_6          0x43c
 149#define VFE_0_BUS_BDG_DS_CFG_7          0x440
 150#define VFE_0_BUS_BDG_DS_CFG_8          0x444
 151#define VFE_0_BUS_BDG_DS_CFG_9          0x448
 152#define VFE_0_BUS_BDG_DS_CFG_10         0x44c
 153#define VFE_0_BUS_BDG_DS_CFG_11         0x450
 154#define VFE_0_BUS_BDG_DS_CFG_12         0x454
 155#define VFE_0_BUS_BDG_DS_CFG_13         0x458
 156#define VFE_0_BUS_BDG_DS_CFG_14         0x45c
 157#define VFE_0_BUS_BDG_DS_CFG_15         0x460
 158#define VFE_0_BUS_BDG_DS_CFG_16         0x464
 159#define VFE_0_BUS_BDG_DS_CFG_16_CFG     0x00000110
 160
 161#define VFE_0_RDI_CFG_x(x)              (0x46c + (0x4 * (x)))
 162#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT    28
 163#define VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK     (0xf << 28)
 164#define VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT        4
 165#define VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK         (0xf << 4)
 166#define VFE_0_RDI_CFG_x_RDI_EN_BIT              BIT(2)
 167#define VFE_0_RDI_CFG_x_MIPI_EN_BITS            0x3
 168
 169#define VFE_0_CAMIF_CMD                         0x478
 170#define VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY  0
 171#define VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY   1
 172#define VFE_0_CAMIF_CMD_NO_CHANGE               3
 173#define VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS      BIT(2)
 174#define VFE_0_CAMIF_CFG                         0x47c
 175#define VFE_0_CAMIF_CFG_VFE_OUTPUT_EN           BIT(6)
 176#define VFE_0_CAMIF_FRAME_CFG                   0x484
 177#define VFE_0_CAMIF_WINDOW_WIDTH_CFG            0x488
 178#define VFE_0_CAMIF_WINDOW_HEIGHT_CFG           0x48c
 179#define VFE_0_CAMIF_SUBSAMPLE_CFG               0x490
 180#define VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN       0x498
 181#define VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN       0x49c
 182#define VFE_0_CAMIF_STATUS                      0x4a4
 183#define VFE_0_CAMIF_STATUS_HALT                 BIT(31)
 184
 185#define VFE_0_REG_UPDATE                0x4ac
 186#define VFE_0_REG_UPDATE_RDIn(n)                BIT(1 + (n))
 187#define VFE_0_REG_UPDATE_line_n(n)              \
 188                        ((n) == VFE_LINE_PIX ? 1 : VFE_0_REG_UPDATE_RDIn(n))
 189
 190#define VFE_0_DEMUX_CFG                         0x560
 191#define VFE_0_DEMUX_CFG_PERIOD                  0x3
 192#define VFE_0_DEMUX_GAIN_0                      0x564
 193#define VFE_0_DEMUX_GAIN_0_CH0_EVEN             (0x80 << 0)
 194#define VFE_0_DEMUX_GAIN_0_CH0_ODD              (0x80 << 16)
 195#define VFE_0_DEMUX_GAIN_1                      0x568
 196#define VFE_0_DEMUX_GAIN_1_CH1                  (0x80 << 0)
 197#define VFE_0_DEMUX_GAIN_1_CH2                  (0x80 << 16)
 198#define VFE_0_DEMUX_EVEN_CFG                    0x574
 199#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV       0x9cac
 200#define VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU       0xac9c
 201#define VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY       0xc9ca
 202#define VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY       0xcac9
 203#define VFE_0_DEMUX_ODD_CFG                     0x578
 204#define VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV        0x9cac
 205#define VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU        0xac9c
 206#define VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY        0xc9ca
 207#define VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY        0xcac9
 208
 209#define VFE_0_SCALE_ENC_Y_CFG                   0x91c
 210#define VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE          0x920
 211#define VFE_0_SCALE_ENC_Y_H_PHASE               0x924
 212#define VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE          0x934
 213#define VFE_0_SCALE_ENC_Y_V_PHASE               0x938
 214#define VFE_0_SCALE_ENC_CBCR_CFG                0x948
 215#define VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE       0x94c
 216#define VFE_0_SCALE_ENC_CBCR_H_PHASE            0x950
 217#define VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE       0x960
 218#define VFE_0_SCALE_ENC_CBCR_V_PHASE            0x964
 219
 220#define VFE_0_CROP_ENC_Y_WIDTH                  0x974
 221#define VFE_0_CROP_ENC_Y_HEIGHT                 0x978
 222#define VFE_0_CROP_ENC_CBCR_WIDTH               0x97c
 223#define VFE_0_CROP_ENC_CBCR_HEIGHT              0x980
 224
 225#define VFE_0_CLAMP_ENC_MAX_CFG                 0x984
 226#define VFE_0_CLAMP_ENC_MAX_CFG_CH0             (0xff << 0)
 227#define VFE_0_CLAMP_ENC_MAX_CFG_CH1             (0xff << 8)
 228#define VFE_0_CLAMP_ENC_MAX_CFG_CH2             (0xff << 16)
 229#define VFE_0_CLAMP_ENC_MIN_CFG                 0x988
 230#define VFE_0_CLAMP_ENC_MIN_CFG_CH0             (0x0 << 0)
 231#define VFE_0_CLAMP_ENC_MIN_CFG_CH1             (0x0 << 8)
 232#define VFE_0_CLAMP_ENC_MIN_CFG_CH2             (0x0 << 16)
 233
 234#define VFE_0_REALIGN_BUF_CFG                   0xaac
 235#define VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL     BIT(2)
 236#define VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL     BIT(3)
 237#define VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE      BIT(4)
 238
 239#define VFE_0_BUS_IMAGE_MASTER_CMD              0xcec
 240#define VFE_0_BUS_IMAGE_MASTER_n_SHIFT(x)       (2 * (x))
 241
 242#define CAMIF_TIMEOUT_SLEEP_US 1000
 243#define CAMIF_TIMEOUT_ALL_US 1000000
 244
 245#define MSM_VFE_VFE0_UB_SIZE 2047
 246#define MSM_VFE_VFE0_UB_SIZE_RDI (MSM_VFE_VFE0_UB_SIZE / 3)
 247#define MSM_VFE_VFE1_UB_SIZE 1535
 248#define MSM_VFE_VFE1_UB_SIZE_RDI (MSM_VFE_VFE1_UB_SIZE / 3)
 249
 250static u32 vfe_hw_version(struct vfe_device *vfe)
 251{
 252        u32 hw_version = readl_relaxed(vfe->base + VFE_0_HW_VERSION);
 253
 254        dev_dbg(vfe->camss->dev, "VFE HW Version = 0x%08x\n", hw_version);
 255
 256        return hw_version;
 257}
 258
 259static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
 260{
 261        u32 bits = readl_relaxed(vfe->base + reg);
 262
 263        writel_relaxed(bits & ~clr_bits, vfe->base + reg);
 264}
 265
 266static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
 267{
 268        u32 bits = readl_relaxed(vfe->base + reg);
 269
 270        writel_relaxed(bits | set_bits, vfe->base + reg);
 271}
 272
 273static void vfe_global_reset(struct vfe_device *vfe)
 274{
 275        u32 reset_bits = VFE_0_GLOBAL_RESET_CMD_IDLE_CGC        |
 276                         VFE_0_GLOBAL_RESET_CMD_DSP             |
 277                         VFE_0_GLOBAL_RESET_CMD_TESTGEN         |
 278                         VFE_0_GLOBAL_RESET_CMD_BUS_MISR        |
 279                         VFE_0_GLOBAL_RESET_CMD_PM              |
 280                         VFE_0_GLOBAL_RESET_CMD_REGISTER        |
 281                         VFE_0_GLOBAL_RESET_CMD_BUS_BDG         |
 282                         VFE_0_GLOBAL_RESET_CMD_BUS             |
 283                         VFE_0_GLOBAL_RESET_CMD_CAMIF           |
 284                         VFE_0_GLOBAL_RESET_CMD_CORE;
 285
 286        writel_relaxed(BIT(31), vfe->base + VFE_0_IRQ_MASK_0);
 287
 288        /* Enforce barrier between IRQ mask setup and global reset */
 289        wmb();
 290        writel_relaxed(reset_bits, vfe->base + VFE_0_GLOBAL_RESET_CMD);
 291}
 292
 293static void vfe_halt_request(struct vfe_device *vfe)
 294{
 295        writel_relaxed(VFE_0_BUS_BDG_CMD_HALT_REQ,
 296                       vfe->base + VFE_0_BUS_BDG_CMD);
 297}
 298
 299static void vfe_halt_clear(struct vfe_device *vfe)
 300{
 301        writel_relaxed(0x0, vfe->base + VFE_0_BUS_BDG_CMD);
 302}
 303
 304static void vfe_wm_frame_based(struct vfe_device *vfe, u8 wm, u8 enable)
 305{
 306        if (enable)
 307                vfe_reg_set(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
 308                            1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
 309        else
 310                vfe_reg_clr(vfe, VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm),
 311                            1 << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_BASED_SHIFT);
 312}
 313
 314#define CALC_WORD(width, M, N) (((width) * (M) + (N) - 1) / (N))
 315
 316static int vfe_word_per_line_by_pixel(u32 format, u32 pixel_per_line)
 317{
 318        int val = 0;
 319
 320        switch (format) {
 321        case V4L2_PIX_FMT_NV12:
 322        case V4L2_PIX_FMT_NV21:
 323        case V4L2_PIX_FMT_NV16:
 324        case V4L2_PIX_FMT_NV61:
 325                val = CALC_WORD(pixel_per_line, 1, 8);
 326                break;
 327        case V4L2_PIX_FMT_YUYV:
 328        case V4L2_PIX_FMT_YVYU:
 329        case V4L2_PIX_FMT_UYVY:
 330        case V4L2_PIX_FMT_VYUY:
 331                val = CALC_WORD(pixel_per_line, 2, 8);
 332                break;
 333        }
 334
 335        return val;
 336}
 337
 338static int vfe_word_per_line_by_bytes(u32 bytes_per_line)
 339{
 340        return CALC_WORD(bytes_per_line, 1, 8);
 341}
 342
 343static void vfe_get_wm_sizes(struct v4l2_pix_format_mplane *pix, u8 plane,
 344                             u16 *width, u16 *height, u16 *bytesperline)
 345{
 346        *width = pix->width;
 347        *height = pix->height;
 348
 349        switch (pix->pixelformat) {
 350        case V4L2_PIX_FMT_NV12:
 351        case V4L2_PIX_FMT_NV21:
 352                *bytesperline = pix->plane_fmt[0].bytesperline;
 353                if (plane == 1)
 354                        *height /= 2;
 355                break;
 356        case V4L2_PIX_FMT_NV16:
 357        case V4L2_PIX_FMT_NV61:
 358                *bytesperline = pix->plane_fmt[0].bytesperline;
 359                break;
 360        case V4L2_PIX_FMT_YUYV:
 361        case V4L2_PIX_FMT_YVYU:
 362        case V4L2_PIX_FMT_VYUY:
 363        case V4L2_PIX_FMT_UYVY:
 364                *bytesperline = pix->plane_fmt[plane].bytesperline;
 365                break;
 366        }
 367}
 368
 369static void vfe_wm_line_based(struct vfe_device *vfe, u32 wm,
 370                              struct v4l2_pix_format_mplane *pix,
 371                              u8 plane, u32 enable)
 372{
 373        u32 reg;
 374
 375        if (enable) {
 376                u16 width = 0, height = 0, bytesperline = 0, wpl;
 377
 378                vfe_get_wm_sizes(pix, plane, &width, &height, &bytesperline);
 379
 380                wpl = vfe_word_per_line_by_pixel(pix->pixelformat, width);
 381
 382                reg = height - 1;
 383                reg |= ((wpl + 3) / 4 - 1) << 16;
 384
 385                writel_relaxed(reg, vfe->base +
 386                               VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
 387
 388                wpl = vfe_word_per_line_by_bytes(bytesperline);
 389
 390                reg = 0x3;
 391                reg |= (height - 1) << 2;
 392                reg |= ((wpl + 1) / 2) << 16;
 393
 394                writel_relaxed(reg, vfe->base +
 395                               VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
 396        } else {
 397                writel_relaxed(0, vfe->base +
 398                               VFE_0_BUS_IMAGE_MASTER_n_WR_IMAGE_SIZE(wm));
 399                writel_relaxed(0, vfe->base +
 400                               VFE_0_BUS_IMAGE_MASTER_n_WR_BUFFER_CFG(wm));
 401        }
 402}
 403
 404static void vfe_wm_set_framedrop_period(struct vfe_device *vfe, u8 wm, u8 per)
 405{
 406        u32 reg;
 407
 408        reg = readl_relaxed(vfe->base +
 409                            VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
 410
 411        reg &= ~(VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK);
 412
 413        reg |= (per << VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_SHIFT)
 414                & VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG_FRM_DROP_PER_MASK;
 415
 416        writel_relaxed(reg,
 417                       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_ADDR_CFG(wm));
 418}
 419
 420static void vfe_wm_set_framedrop_pattern(struct vfe_device *vfe, u8 wm,
 421                                         u32 pattern)
 422{
 423        writel_relaxed(pattern, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_FRAMEDROP_PATTERN(wm));
 424}
 425
 426static void vfe_wm_set_ub_cfg(struct vfe_device *vfe, u8 wm,
 427                              u16 offset, u16 depth)
 428{
 429        u32 reg;
 430
 431        reg = (offset << VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG_OFFSET_SHIFT) |
 432              depth;
 433        writel_relaxed(reg, vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_UB_CFG(wm));
 434}
 435
 436static void vfe_bus_reload_wm(struct vfe_device *vfe, u8 wm)
 437{
 438        /* Enforce barrier between any outstanding register write */
 439        wmb();
 440
 441        writel_relaxed(VFE_0_BUS_CMD_Mx_RLD_CMD(wm), vfe->base + VFE_0_BUS_CMD);
 442
 443        /* Use barrier to make sure bus reload is issued before anything else */
 444        wmb();
 445}
 446
 447static void vfe_wm_set_ping_addr(struct vfe_device *vfe, u8 wm, u32 addr)
 448{
 449        writel_relaxed(addr,
 450                       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PING_ADDR(wm));
 451}
 452
 453static void vfe_wm_set_pong_addr(struct vfe_device *vfe, u8 wm, u32 addr)
 454{
 455        writel_relaxed(addr,
 456                       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_PONG_ADDR(wm));
 457}
 458
 459static int vfe_wm_get_ping_pong_status(struct vfe_device *vfe, u8 wm)
 460{
 461        u32 reg;
 462
 463        reg = readl_relaxed(vfe->base + VFE_0_BUS_PING_PONG_STATUS);
 464
 465        return (reg >> wm) & 0x1;
 466}
 467
 468static void vfe_bus_enable_wr_if(struct vfe_device *vfe, u8 enable)
 469{
 470        if (enable)
 471                writel_relaxed(0x101, vfe->base + VFE_0_BUS_CFG);
 472        else
 473                writel_relaxed(0, vfe->base + VFE_0_BUS_CFG);
 474}
 475
 476static void vfe_bus_connect_wm_to_rdi(struct vfe_device *vfe, u8 wm,
 477                                      enum vfe_line_id id)
 478{
 479        u32 reg;
 480
 481        reg = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
 482        vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), reg);
 483
 484        reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
 485        reg |= ((3 * id) << VFE_0_RDI_CFG_x_RDI_STREAM_SEL_SHIFT) &
 486                VFE_0_RDI_CFG_x_RDI_STREAM_SEL_MASK;
 487        vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id), reg);
 488
 489        switch (id) {
 490        case VFE_LINE_RDI0:
 491        default:
 492                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
 493                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 494                break;
 495        case VFE_LINE_RDI1:
 496                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
 497                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 498                break;
 499        case VFE_LINE_RDI2:
 500                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
 501                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 502                break;
 503        }
 504
 505        if (wm % 2 == 1)
 506                reg <<= 16;
 507
 508        vfe_reg_set(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
 509}
 510
 511static void vfe_wm_set_subsample(struct vfe_device *vfe, u8 wm)
 512{
 513        writel_relaxed(VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN_DEF,
 514                       vfe->base + VFE_0_BUS_IMAGE_MASTER_n_WR_IRQ_SUBSAMPLE_PATTERN(wm));
 515}
 516
 517static void vfe_bus_disconnect_wm_from_rdi(struct vfe_device *vfe, u8 wm,
 518                                           enum vfe_line_id id)
 519{
 520        u32 reg;
 521
 522        reg = VFE_0_RDI_CFG_x_RDI_EN_BIT;
 523        vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id), reg);
 524
 525        switch (id) {
 526        case VFE_LINE_RDI0:
 527        default:
 528                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI0 <<
 529                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 530                break;
 531        case VFE_LINE_RDI1:
 532                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI1 <<
 533                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 534                break;
 535        case VFE_LINE_RDI2:
 536                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_VAL_RDI2 <<
 537                      VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 538                break;
 539        }
 540
 541        if (wm % 2 == 1)
 542                reg <<= 16;
 543
 544        vfe_reg_clr(vfe, VFE_0_BUS_XBAR_CFG_x(wm), reg);
 545}
 546
 547static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output,
 548                             u8 enable)
 549{
 550        struct vfe_line *line = container_of(output, struct vfe_line, output);
 551        u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
 552        u32 reg;
 553
 554        switch (p) {
 555        case V4L2_PIX_FMT_NV12:
 556        case V4L2_PIX_FMT_NV21:
 557        case V4L2_PIX_FMT_NV16:
 558        case V4L2_PIX_FMT_NV61:
 559                reg = VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_LUMA <<
 560                        VFE_0_BUS_XBAR_CFG_x_M_SINGLE_STREAM_SEL_SHIFT;
 561
 562                if (output->wm_idx[0] % 2 == 1)
 563                        reg <<= 16;
 564
 565                if (enable)
 566                        vfe_reg_set(vfe,
 567                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
 568                                    reg);
 569                else
 570                        vfe_reg_clr(vfe,
 571                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
 572                                    reg);
 573
 574                reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
 575                if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16)
 576                        reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
 577
 578                if (output->wm_idx[1] % 2 == 1)
 579                        reg <<= 16;
 580
 581                if (enable)
 582                        vfe_reg_set(vfe,
 583                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
 584                                    reg);
 585                else
 586                        vfe_reg_clr(vfe,
 587                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[1]),
 588                                    reg);
 589                break;
 590        case V4L2_PIX_FMT_YUYV:
 591        case V4L2_PIX_FMT_YVYU:
 592        case V4L2_PIX_FMT_VYUY:
 593        case V4L2_PIX_FMT_UYVY:
 594                reg = VFE_0_BUS_XBAR_CFG_x_M_REALIGN_BUF_EN;
 595                reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN;
 596
 597                if (p == V4L2_PIX_FMT_YUYV || p == V4L2_PIX_FMT_YVYU)
 598                        reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA;
 599
 600                if (output->wm_idx[0] % 2 == 1)
 601                        reg <<= 16;
 602
 603                if (enable)
 604                        vfe_reg_set(vfe,
 605                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
 606                                    reg);
 607                else
 608                        vfe_reg_clr(vfe,
 609                                    VFE_0_BUS_XBAR_CFG_x(output->wm_idx[0]),
 610                                    reg);
 611                break;
 612        default:
 613                break;
 614        }
 615}
 616
 617static void vfe_set_realign_cfg(struct vfe_device *vfe, struct vfe_line *line,
 618                                u8 enable)
 619{
 620        u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
 621        u32 val = VFE_0_MODULE_ZOOM_EN_REALIGN_BUF;
 622
 623        if (p != V4L2_PIX_FMT_YUYV && p != V4L2_PIX_FMT_YVYU &&
 624            p != V4L2_PIX_FMT_VYUY && p != V4L2_PIX_FMT_UYVY)
 625                return;
 626
 627        if (enable) {
 628                vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val);
 629        } else {
 630                vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val);
 631                return;
 632        }
 633
 634        val = VFE_0_REALIGN_BUF_CFG_HSUB_ENABLE;
 635
 636        if (p == V4L2_PIX_FMT_UYVY || p == V4L2_PIX_FMT_YUYV)
 637                val |= VFE_0_REALIGN_BUF_CFG_CR_ODD_PIXEL;
 638        else
 639                val |= VFE_0_REALIGN_BUF_CFG_CB_ODD_PIXEL;
 640
 641        writel_relaxed(val, vfe->base + VFE_0_REALIGN_BUF_CFG);
 642}
 643
 644static void vfe_set_rdi_cid(struct vfe_device *vfe, enum vfe_line_id id, u8 cid)
 645{
 646        vfe_reg_clr(vfe, VFE_0_RDI_CFG_x(id),
 647                    VFE_0_RDI_CFG_x_RDI_M0_SEL_MASK);
 648
 649        vfe_reg_set(vfe, VFE_0_RDI_CFG_x(id),
 650                    cid << VFE_0_RDI_CFG_x_RDI_M0_SEL_SHIFT);
 651}
 652
 653static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
 654{
 655        vfe->reg_update |= VFE_0_REG_UPDATE_line_n(line_id);
 656
 657        /* Enforce barrier between line update and commit */
 658        wmb();
 659
 660        writel_relaxed(vfe->reg_update, vfe->base + VFE_0_REG_UPDATE);
 661
 662        /* Make sure register update is issued before further reg writes */
 663        wmb();
 664}
 665
 666static inline void vfe_reg_update_clear(struct vfe_device *vfe,
 667                                        enum vfe_line_id line_id)
 668{
 669        vfe->reg_update &= ~VFE_0_REG_UPDATE_line_n(line_id);
 670}
 671
 672static void vfe_enable_irq_wm_line(struct vfe_device *vfe, u8 wm,
 673                                   enum vfe_line_id line_id, u8 enable)
 674{
 675        u32 irq_en0 = VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(wm) |
 676                      VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
 677        u32 irq_en1 = VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(wm) |
 678                      VFE_0_IRQ_MASK_1_RDIn_SOF(line_id);
 679
 680        if (enable) {
 681                vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
 682                vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
 683        } else {
 684                vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
 685                vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
 686        }
 687}
 688
 689static void vfe_enable_irq_pix_line(struct vfe_device *vfe, u8 comp,
 690                                    enum vfe_line_id line_id, u8 enable)
 691{
 692        struct vfe_output *output = &vfe->line[line_id].output;
 693        unsigned int i;
 694        u32 irq_en0;
 695        u32 irq_en1;
 696        u32 comp_mask = 0;
 697
 698        irq_en0 = VFE_0_IRQ_MASK_0_CAMIF_SOF;
 699        irq_en0 |= VFE_0_IRQ_MASK_0_CAMIF_EOF;
 700        irq_en0 |= VFE_0_IRQ_MASK_0_IMAGE_COMPOSITE_DONE_n(comp);
 701        irq_en0 |= VFE_0_IRQ_MASK_0_line_n_REG_UPDATE(line_id);
 702        irq_en1 = VFE_0_IRQ_MASK_1_CAMIF_ERROR;
 703        for (i = 0; i < output->wm_num; i++) {
 704                irq_en1 |= VFE_0_IRQ_MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(output->wm_idx[i]);
 705                comp_mask |= (1 << output->wm_idx[i]) << comp * 8;
 706        }
 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                vfe_reg_set(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
 712        } else {
 713                vfe_reg_clr(vfe, VFE_0_IRQ_MASK_0, irq_en0);
 714                vfe_reg_clr(vfe, VFE_0_IRQ_MASK_1, irq_en1);
 715                vfe_reg_clr(vfe, VFE_0_IRQ_COMPOSITE_MASK_0, comp_mask);
 716        }
 717}
 718
 719static void vfe_enable_irq_common(struct vfe_device *vfe)
 720{
 721        u32 irq_en0 = VFE_0_IRQ_MASK_0_RESET_ACK;
 722        u32 irq_en1 = VFE_0_IRQ_MASK_1_VIOLATION |
 723                      VFE_0_IRQ_MASK_1_BUS_BDG_HALT_ACK;
 724
 725        vfe_reg_set(vfe, VFE_0_IRQ_MASK_0, irq_en0);
 726        vfe_reg_set(vfe, VFE_0_IRQ_MASK_1, irq_en1);
 727}
 728
 729static void vfe_set_demux_cfg(struct vfe_device *vfe, struct vfe_line *line)
 730{
 731        u32 val, even_cfg, odd_cfg;
 732
 733        writel_relaxed(VFE_0_DEMUX_CFG_PERIOD, vfe->base + VFE_0_DEMUX_CFG);
 734
 735        val = VFE_0_DEMUX_GAIN_0_CH0_EVEN | VFE_0_DEMUX_GAIN_0_CH0_ODD;
 736        writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_0);
 737
 738        val = VFE_0_DEMUX_GAIN_1_CH1 | VFE_0_DEMUX_GAIN_1_CH2;
 739        writel_relaxed(val, vfe->base + VFE_0_DEMUX_GAIN_1);
 740
 741        switch (line->fmt[MSM_VFE_PAD_SINK].code) {
 742        case MEDIA_BUS_FMT_YUYV8_2X8:
 743                even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YUYV;
 744                odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YUYV;
 745                break;
 746        case MEDIA_BUS_FMT_YVYU8_2X8:
 747                even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_YVYU;
 748                odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_YVYU;
 749                break;
 750        case MEDIA_BUS_FMT_UYVY8_2X8:
 751        default:
 752                even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_UYVY;
 753                odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_UYVY;
 754                break;
 755        case MEDIA_BUS_FMT_VYUY8_2X8:
 756                even_cfg = VFE_0_DEMUX_EVEN_CFG_PATTERN_VYUY;
 757                odd_cfg = VFE_0_DEMUX_ODD_CFG_PATTERN_VYUY;
 758                break;
 759        }
 760
 761        writel_relaxed(even_cfg, vfe->base + VFE_0_DEMUX_EVEN_CFG);
 762        writel_relaxed(odd_cfg, vfe->base + VFE_0_DEMUX_ODD_CFG);
 763}
 764
 765static void vfe_set_scale_cfg(struct vfe_device *vfe, struct vfe_line *line)
 766{
 767        u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
 768        u32 reg;
 769        u16 input, output;
 770        u8 interp_reso;
 771        u32 phase_mult;
 772
 773        writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_Y_CFG);
 774
 775        input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
 776        output = line->compose.width - 1;
 777        reg = (output << 16) | input;
 778        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_IMAGE_SIZE);
 779
 780        interp_reso = vfe_calc_interp_reso(input, output);
 781        phase_mult = input * (1 << (14 + interp_reso)) / output;
 782        reg = (interp_reso << 28) | phase_mult;
 783        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_H_PHASE);
 784
 785        input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
 786        output = line->compose.height - 1;
 787        reg = (output << 16) | input;
 788        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_IMAGE_SIZE);
 789
 790        interp_reso = vfe_calc_interp_reso(input, output);
 791        phase_mult = input * (1 << (14 + interp_reso)) / output;
 792        reg = (interp_reso << 28) | phase_mult;
 793        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_Y_V_PHASE);
 794
 795        writel_relaxed(0x3, vfe->base + VFE_0_SCALE_ENC_CBCR_CFG);
 796
 797        input = line->fmt[MSM_VFE_PAD_SINK].width - 1;
 798        output = line->compose.width / 2 - 1;
 799        reg = (output << 16) | input;
 800        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_IMAGE_SIZE);
 801
 802        interp_reso = vfe_calc_interp_reso(input, output);
 803        phase_mult = input * (1 << (14 + interp_reso)) / output;
 804        reg = (interp_reso << 28) | phase_mult;
 805        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_H_PHASE);
 806
 807        input = line->fmt[MSM_VFE_PAD_SINK].height - 1;
 808        output = line->compose.height - 1;
 809        if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21)
 810                output = line->compose.height / 2 - 1;
 811        reg = (output << 16) | input;
 812        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_IMAGE_SIZE);
 813
 814        interp_reso = vfe_calc_interp_reso(input, output);
 815        phase_mult = input * (1 << (14 + interp_reso)) / output;
 816        reg = (interp_reso << 28) | phase_mult;
 817        writel_relaxed(reg, vfe->base + VFE_0_SCALE_ENC_CBCR_V_PHASE);
 818}
 819
 820static void vfe_set_crop_cfg(struct vfe_device *vfe, struct vfe_line *line)
 821{
 822        u32 p = line->video_out.active_fmt.fmt.pix_mp.pixelformat;
 823        u32 reg;
 824        u16 first, last;
 825
 826        first = line->crop.left;
 827        last = line->crop.left + line->crop.width - 1;
 828        reg = (first << 16) | last;
 829        writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_WIDTH);
 830
 831        first = line->crop.top;
 832        last = line->crop.top + line->crop.height - 1;
 833        reg = (first << 16) | last;
 834        writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_Y_HEIGHT);
 835
 836        first = line->crop.left / 2;
 837        last = line->crop.left / 2 + line->crop.width / 2 - 1;
 838        reg = (first << 16) | last;
 839        writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_WIDTH);
 840
 841        first = line->crop.top;
 842        last = line->crop.top + line->crop.height - 1;
 843        if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV21) {
 844                first = line->crop.top / 2;
 845                last = line->crop.top / 2 + line->crop.height / 2 - 1;
 846        }
 847        reg = (first << 16) | last;
 848        writel_relaxed(reg, vfe->base + VFE_0_CROP_ENC_CBCR_HEIGHT);
 849}
 850
 851static void vfe_set_clamp_cfg(struct vfe_device *vfe)
 852{
 853        u32 val = VFE_0_CLAMP_ENC_MAX_CFG_CH0 |
 854                VFE_0_CLAMP_ENC_MAX_CFG_CH1 |
 855                VFE_0_CLAMP_ENC_MAX_CFG_CH2;
 856
 857        writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MAX_CFG);
 858
 859        val = VFE_0_CLAMP_ENC_MIN_CFG_CH0 |
 860                VFE_0_CLAMP_ENC_MIN_CFG_CH1 |
 861                VFE_0_CLAMP_ENC_MIN_CFG_CH2;
 862
 863        writel_relaxed(val, vfe->base + VFE_0_CLAMP_ENC_MIN_CFG);
 864}
 865
 866static void vfe_set_cgc_override(struct vfe_device *vfe, u8 wm, u8 enable)
 867{
 868        /* empty */
 869}
 870
 871static void vfe_set_camif_cfg(struct vfe_device *vfe, struct vfe_line *line)
 872{
 873        u32 val;
 874
 875        switch (line->fmt[MSM_VFE_PAD_SINK].code) {
 876        case MEDIA_BUS_FMT_YUYV8_2X8:
 877                val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCBYCR;
 878                break;
 879        case MEDIA_BUS_FMT_YVYU8_2X8:
 880                val = VFE_0_CORE_CFG_PIXEL_PATTERN_YCRYCB;
 881                break;
 882        case MEDIA_BUS_FMT_UYVY8_2X8:
 883        default:
 884                val = VFE_0_CORE_CFG_PIXEL_PATTERN_CBYCRY;
 885                break;
 886        case MEDIA_BUS_FMT_VYUY8_2X8:
 887                val = VFE_0_CORE_CFG_PIXEL_PATTERN_CRYCBY;
 888                break;
 889        }
 890
 891        val |= VFE_0_CORE_CFG_COMPOSITE_REG_UPDATE_EN;
 892        writel_relaxed(val, vfe->base + VFE_0_CORE_CFG);
 893
 894        val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
 895        val |= (line->fmt[MSM_VFE_PAD_SINK].height - 1) << 16;
 896        writel_relaxed(val, vfe->base + VFE_0_CAMIF_FRAME_CFG);
 897
 898        val = line->fmt[MSM_VFE_PAD_SINK].width * 2 - 1;
 899        writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_WIDTH_CFG);
 900
 901        val = line->fmt[MSM_VFE_PAD_SINK].height - 1;
 902        writel_relaxed(val, vfe->base + VFE_0_CAMIF_WINDOW_HEIGHT_CFG);
 903
 904        val = 0xffffffff;
 905        writel_relaxed(val, vfe->base + VFE_0_CAMIF_SUBSAMPLE_CFG);
 906
 907        val = 0xffffffff;
 908        writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_FRAMEDROP_PATTERN);
 909
 910        val = 0xffffffff;
 911        writel_relaxed(val, vfe->base + VFE_0_CAMIF_IRQ_SUBSAMPLE_PATTERN);
 912
 913        val = VFE_0_RDI_CFG_x_MIPI_EN_BITS;
 914        vfe_reg_set(vfe, VFE_0_RDI_CFG_x(0), val);
 915
 916        val = VFE_0_CAMIF_CFG_VFE_OUTPUT_EN;
 917        writel_relaxed(val, vfe->base + VFE_0_CAMIF_CFG);
 918}
 919
 920static void vfe_set_camif_cmd(struct vfe_device *vfe, u8 enable)
 921{
 922        u32 cmd;
 923
 924        cmd = VFE_0_CAMIF_CMD_CLEAR_CAMIF_STATUS | VFE_0_CAMIF_CMD_NO_CHANGE;
 925        writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
 926
 927        /* Make sure camif command is issued written before it is changed again */
 928        wmb();
 929
 930        if (enable)
 931                cmd = VFE_0_CAMIF_CMD_ENABLE_FRAME_BOUNDARY;
 932        else
 933                cmd = VFE_0_CAMIF_CMD_DISABLE_FRAME_BOUNDARY;
 934
 935        writel_relaxed(cmd, vfe->base + VFE_0_CAMIF_CMD);
 936}
 937
 938static void vfe_set_module_cfg(struct vfe_device *vfe, u8 enable)
 939{
 940        u32 val_lens = VFE_0_MODULE_LENS_EN_DEMUX |
 941                       VFE_0_MODULE_LENS_EN_CHROMA_UPSAMPLE;
 942        u32 val_zoom = VFE_0_MODULE_ZOOM_EN_SCALE_ENC |
 943                       VFE_0_MODULE_ZOOM_EN_CROP_ENC;
 944
 945        if (enable) {
 946                vfe_reg_set(vfe, VFE_0_MODULE_LENS_EN, val_lens);
 947                vfe_reg_set(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
 948        } else {
 949                vfe_reg_clr(vfe, VFE_0_MODULE_LENS_EN, val_lens);
 950                vfe_reg_clr(vfe, VFE_0_MODULE_ZOOM_EN, val_zoom);
 951        }
 952}
 953
 954static int vfe_camif_wait_for_stop(struct vfe_device *vfe, struct device *dev)
 955{
 956        u32 val;
 957        int ret;
 958
 959        ret = readl_poll_timeout(vfe->base + VFE_0_CAMIF_STATUS,
 960                                 val,
 961                                 (val & VFE_0_CAMIF_STATUS_HALT),
 962                                 CAMIF_TIMEOUT_SLEEP_US,
 963                                 CAMIF_TIMEOUT_ALL_US);
 964        if (ret < 0)
 965                dev_err(dev, "%s: camif stop timeout\n", __func__);
 966
 967        return ret;
 968}
 969
 970/*
 971 * vfe_isr - VFE module interrupt handler
 972 * @irq: Interrupt line
 973 * @dev: VFE device
 974 *
 975 * Return IRQ_HANDLED on success
 976 */
 977static irqreturn_t vfe_isr(int irq, void *dev)
 978{
 979        struct vfe_device *vfe = dev;
 980        u32 value0, value1;
 981        int i, j;
 982
 983        vfe->ops->isr_read(vfe, &value0, &value1);
 984
 985        dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 986                value0, value1);
 987
 988        if (value0 & VFE_0_IRQ_STATUS_0_RESET_ACK)
 989                vfe->isr_ops.reset_ack(vfe);
 990
 991        if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
 992                vfe->ops->violation_read(vfe);
 993
 994        if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
 995                vfe->isr_ops.halt_ack(vfe);
 996
 997        for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
 998                if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
 999                        vfe->isr_ops.reg_update(vfe, i);
1000
1001        if (value0 & VFE_0_IRQ_STATUS_0_CAMIF_SOF)
1002                vfe->isr_ops.sof(vfe, VFE_LINE_PIX);
1003
1004        for (i = VFE_LINE_RDI0; i <= VFE_LINE_RDI2; i++)
1005                if (value1 & VFE_0_IRQ_STATUS_1_RDIn_SOF(i))
1006                        vfe->isr_ops.sof(vfe, i);
1007
1008        for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
1009                if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_COMPOSITE_DONE_n(i)) {
1010                        vfe->isr_ops.comp_done(vfe, i);
1011                        for (j = 0; j < ARRAY_SIZE(vfe->wm_output_map); j++)
1012                                if (vfe->wm_output_map[j] == VFE_LINE_PIX)
1013                                        value0 &= ~VFE_0_IRQ_MASK_0_IMAGE_MASTER_n_PING_PONG(j);
1014                }
1015
1016        for (i = 0; i < MSM_VFE_IMAGE_MASTERS_NUM; i++)
1017                if (value0 & VFE_0_IRQ_STATUS_0_IMAGE_MASTER_n_PING_PONG(i))
1018                        vfe->isr_ops.wm_done(vfe, i);
1019
1020        return IRQ_HANDLED;
1021}
1022
1023static u16 vfe_get_ub_size(u8 vfe_id)
1024{
1025        /* On VFE4.8 the ub-size is the same on both instances */
1026        return MSM_VFE_VFE0_UB_SIZE_RDI;
1027}
1028
1029static void vfe_wm_enable(struct vfe_device *vfe, u8 wm, u8 enable)
1030{
1031        if (enable)
1032                writel_relaxed(2 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1033                               vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1034        else
1035                writel_relaxed(1 << VFE_0_BUS_IMAGE_MASTER_n_SHIFT(wm),
1036                               vfe->base + VFE_0_BUS_IMAGE_MASTER_CMD);
1037
1038        /* The WM must be enabled before sending other commands */
1039        wmb();
1040}
1041
1042static void vfe_set_qos(struct vfe_device *vfe)
1043{
1044        u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
1045        u32 val3 = VFE_0_BUS_BDG_QOS_CFG_3_CFG;
1046        u32 val4 = VFE_0_BUS_BDG_QOS_CFG_4_CFG;
1047        u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
1048
1049        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
1050        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
1051        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_2);
1052        writel_relaxed(val3, vfe->base + VFE_0_BUS_BDG_QOS_CFG_3);
1053        writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_4);
1054        writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
1055        writel_relaxed(val4, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
1056        writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
1057}
1058
1059static void vfe_set_ds(struct vfe_device *vfe)
1060{
1061        u32 val = VFE_0_BUS_BDG_DS_CFG_0_CFG;
1062        u32 val16 = VFE_0_BUS_BDG_DS_CFG_16_CFG;
1063
1064        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_0);
1065        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_1);
1066        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_2);
1067        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_3);
1068        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_4);
1069        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_5);
1070        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_6);
1071        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_7);
1072        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_8);
1073        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_9);
1074        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_10);
1075        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_11);
1076        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_12);
1077        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_13);
1078        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_14);
1079        writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_DS_CFG_15);
1080        writel_relaxed(val16, vfe->base + VFE_0_BUS_BDG_DS_CFG_16);
1081}
1082
1083static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
1084{
1085        *value0 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_0);
1086        *value1 = readl_relaxed(vfe->base + VFE_0_IRQ_STATUS_1);
1087
1088        writel_relaxed(*value0, vfe->base + VFE_0_IRQ_CLEAR_0);
1089        writel_relaxed(*value1, vfe->base + VFE_0_IRQ_CLEAR_1);
1090
1091        /* Enforce barrier between local & global IRQ clear */
1092        wmb();
1093        writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
1094}
1095
1096/*
1097 * vfe_pm_domain_off - Disable power domains specific to this VFE.
1098 * @vfe: VFE Device
1099 */
1100static void vfe_pm_domain_off(struct vfe_device *vfe)
1101{
1102        struct camss *camss = vfe->camss;
1103
1104        device_link_del(camss->genpd_link[vfe->id]);
1105}
1106
1107/*
1108 * vfe_pm_domain_on - Enable power domains specific to this VFE.
1109 * @vfe: VFE Device
1110 */
1111static int vfe_pm_domain_on(struct vfe_device *vfe)
1112{
1113        struct camss *camss = vfe->camss;
1114        enum vfe_line_id id = vfe->id;
1115
1116        camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
1117                                                DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
1118
1119        if (!camss->genpd_link[id]) {
1120                dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
1121                return -EINVAL;
1122        }
1123
1124        return 0;
1125}
1126
1127static void vfe_violation_read(struct vfe_device *vfe)
1128{
1129        u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
1130
1131        pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
1132}
1133
1134static const struct vfe_hw_ops_gen1 vfe_ops_gen1_4_8 = {
1135        .bus_connect_wm_to_rdi = vfe_bus_connect_wm_to_rdi,
1136        .bus_disconnect_wm_from_rdi = vfe_bus_disconnect_wm_from_rdi,
1137        .bus_enable_wr_if = vfe_bus_enable_wr_if,
1138        .bus_reload_wm = vfe_bus_reload_wm,
1139        .camif_wait_for_stop = vfe_camif_wait_for_stop,
1140        .enable_irq_common = vfe_enable_irq_common,
1141        .enable_irq_pix_line = vfe_enable_irq_pix_line,
1142        .enable_irq_wm_line = vfe_enable_irq_wm_line,
1143        .get_ub_size = vfe_get_ub_size,
1144        .halt_clear = vfe_halt_clear,
1145        .halt_request = vfe_halt_request,
1146        .set_camif_cfg = vfe_set_camif_cfg,
1147        .set_camif_cmd = vfe_set_camif_cmd,
1148        .set_cgc_override = vfe_set_cgc_override,
1149        .set_clamp_cfg = vfe_set_clamp_cfg,
1150        .set_crop_cfg = vfe_set_crop_cfg,
1151        .set_demux_cfg = vfe_set_demux_cfg,
1152        .set_ds = vfe_set_ds,
1153        .set_module_cfg = vfe_set_module_cfg,
1154        .set_qos = vfe_set_qos,
1155        .set_rdi_cid = vfe_set_rdi_cid,
1156        .set_realign_cfg = vfe_set_realign_cfg,
1157        .set_scale_cfg = vfe_set_scale_cfg,
1158        .set_xbar_cfg = vfe_set_xbar_cfg,
1159        .wm_enable = vfe_wm_enable,
1160        .wm_frame_based = vfe_wm_frame_based,
1161        .wm_get_ping_pong_status = vfe_wm_get_ping_pong_status,
1162        .wm_line_based = vfe_wm_line_based,
1163        .wm_set_framedrop_pattern = vfe_wm_set_framedrop_pattern,
1164        .wm_set_framedrop_period = vfe_wm_set_framedrop_period,
1165        .wm_set_ping_addr = vfe_wm_set_ping_addr,
1166        .wm_set_pong_addr = vfe_wm_set_pong_addr,
1167        .wm_set_subsample = vfe_wm_set_subsample,
1168        .wm_set_ub_cfg = vfe_wm_set_ub_cfg,
1169};
1170
1171static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
1172{
1173        vfe->isr_ops = vfe_isr_ops_gen1;
1174        vfe->ops_gen1 = &vfe_ops_gen1_4_8;
1175        vfe->video_ops = vfe_video_ops_gen1;
1176
1177        vfe->line_num = VFE_LINE_NUM_GEN1;
1178}
1179
1180const struct vfe_hw_ops vfe_ops_4_8 = {
1181        .global_reset = vfe_global_reset,
1182        .hw_version = vfe_hw_version,
1183        .isr_read = vfe_isr_read,
1184        .isr = vfe_isr,
1185        .pm_domain_off = vfe_pm_domain_off,
1186        .pm_domain_on = vfe_pm_domain_on,
1187        .reg_update_clear = vfe_reg_update_clear,
1188        .reg_update = vfe_reg_update,
1189        .subdev_init = vfe_subdev_init,
1190        .vfe_disable = vfe_gen1_disable,
1191        .vfe_enable = vfe_gen1_enable,
1192        .vfe_halt = vfe_gen1_halt,
1193        .violation_read = vfe_violation_read,
1194};
1195