// SPDX-License-Identifier: GPL-2.0
/*
* camss-ispif.c
*
* Qualcomm MSM Camera Subsystem - ISPIF (ISP Interface) Module
*
* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Copyright (C) 2015-2018 Linaro Ltd.
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <media/media-entity.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include "camss-ispif.h"
#include "camss.h"
#define MSM_ISPIF_NAME "msm_ispif"
#define ISPIF_RST_CMD_0 0x008
#define ISPIF_RST_CMD_0_STROBED_RST_EN (1 << 0)
#define ISPIF_RST_CMD_0_MISC_LOGIC_RST (1 << 1)
#define ISPIF_RST_CMD_0_SW_REG_RST (1 << 2)
#define ISPIF_RST_CMD_0_PIX_INTF_0_CSID_RST (1 << 3)
#define ISPIF_RST_CMD_0_PIX_INTF_0_VFE_RST (1 << 4)
#define ISPIF_RST_CMD_0_PIX_INTF_1_CSID_RST (1 << 5)
#define ISPIF_RST_CMD_0_PIX_INTF_1_VFE_RST (1 << 6)
#define ISPIF_RST_CMD_0_RDI_INTF_0_CSID_RST (1 << 7)
#define ISPIF_RST_CMD_0_RDI_INTF_0_VFE_RST (1 << 8)
#define ISPIF_RST_CMD_0_RDI_INTF_1_CSID_RST (1 << 9)
#define ISPIF_RST_CMD_0_RDI_INTF_1_VFE_RST (1 << 10)
#define ISPIF_RST_CMD_0_RDI_INTF_2_CSID_RST (1 << 11)
#define ISPIF_RST_CMD_0_RDI_INTF_2_VFE_RST (1 << 12)
#define ISPIF_RST_CMD_0_PIX_OUTPUT_0_MISR_RST (1 << 16)
#define ISPIF_RST_CMD_0_RDI_OUTPUT_0_MISR_RST (1 << 17)
#define ISPIF_RST_CMD_0_RDI_OUTPUT_1_MISR_RST (1 << 18)
#define ISPIF_RST_CMD_0_RDI_OUTPUT_2_MISR_RST (1 << 19)
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x01c
#define ISPIF_VFE_m_CTRL_0(m) (0x200 + 0x200 * (m))
#define ISPIF_VFE_m_CTRL_0_PIX0_LINE_BUF_EN (1 << 6)
#define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_ENABLE 0x00001249
#define ISPIF_VFE_m_IRQ_MASK_0_PIX0_MASK 0x00001fff
#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_ENABLE 0x02492000
#define ISPIF_VFE_m_IRQ_MASK_0_RDI0_MASK 0x03ffe000
#define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20c + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_ENABLE 0x00001249
#define ISPIF_VFE_m_IRQ_MASK_1_PIX1_MASK 0x00001fff
#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_ENABLE 0x02492000
#define ISPIF_VFE_m_IRQ_MASK_1_RDI1_MASK 0x03ffe000
#define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_ENABLE 0x00001249
#define ISPIF_VFE_m_IRQ_MASK_2_RDI2_MASK 0x00001fff
#define ISPIF_VFE_m_IRQ_STATUS_0(m) (0x21c + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_STATUS_0_PIX0_OVERFLOW (1 << 12)
#define ISPIF_VFE_m_IRQ_STATUS_0_RDI0_OVERFLOW (1 << 25)
#define ISPIF_VFE_m_IRQ_STATUS_1(m) (0x220 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_STATUS_1_PIX1_OVERFLOW (1 << 12)
#define ISPIF_VFE_m_IRQ_STATUS_1_RDI1_OVERFLOW (1 << 25)
#define ISPIF_VFE_m_IRQ_STATUS_2(m) (0x224 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_STATUS_2_RDI2_OVERFLOW (1 << 12)
#define ISPIF_VFE_m_IRQ_CLEAR_0(m) (0x230 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_CLEAR_1(m) (0x234 + 0x200 * (m))
#define ISPIF_VFE_m_IRQ_CLEAR_2(m) (0x238 + 0x200 * (m))
#define ISPIF_VFE_m_INTF_INPUT_SEL(m) (0x244 + 0x200 * (m))
#define ISPIF_VFE_m_INTF_CMD_0(m) (0x248 + 0x200 * (m))
#define ISPIF_VFE_m_INTF_CMD_1(m) (0x24c + 0x200 * (m))
#define ISPIF_VFE_m_PIX_INTF_n_CID_MASK(m, n) \
(0x254 + 0x200 * (m) + 0x4 * (n))
#define ISPIF_VFE_m_RDI_INTF_n_CID_MASK(m, n) \
(0x264 + 0x200 * (m) + 0x4 * (n))
/* PACK_CFG registers are 8x96 only */
#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0(m, n) \
(0x270 + 0x200 * (m) + 0x4 * (n))
#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_1(m, n) \
(0x27c + 0x200 * (m) + 0x4 * (n))
#define ISPIF_VFE_m_RDI_INTF_n_PACK_CFG_0_CID_c_PLAIN(c) \
(1 << ((cid % 8) * 4))
#define ISPIF_VFE_m_PIX_INTF_n_STATUS(m, n) \
(0x2c0 + 0x200 * (m) + 0x4 * (n))
#define ISPIF_VFE_m_RDI_INTF_n_STATUS(m, n) \
(0x2d0 + 0x200 * (m) + 0x4 * (n))
#define CSI_PIX_CLK_MUX_SEL 0x000
#define CSI_RDI_CLK_MUX_SEL 0x008
#define ISPIF_TIMEOUT_SLEEP_US 1000
#define ISPIF_TIMEOUT_ALL_US 1000000
#define ISPIF_RESET_TIMEOUT_MS 500
enum ispif_intf_cmd {
CMD_DISABLE_FRAME_BOUNDARY = 0x0,
CMD_ENABLE_FRAME_BOUNDARY = 0x1,
CMD_DISABLE_IMMEDIATELY = 0x2,
CMD_ALL_DISABLE_IMMEDIATELY = 0xaaaaaaaa,
CMD_ALL_NO_CHANGE = 0xffffffff,
};
static const u32 ispif_formats_8x16[] = {
MEDIA_BUS_FMT_UYVY8_2X8,
MEDIA_BUS_FMT_V