// SPDX-License-Identifier: GPL-2.0
/*
* camss-csid.c
*
* Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
*
* Copyright (c) 2011-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/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <media/media-entity.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include "camss-csid.h"
#include "camss.h"
#define MSM_CSID_NAME "msm_csid"
#define CAMSS_CSID_HW_VERSION 0x0
#define CAMSS_CSID_CORE_CTRL_0 0x004
#define CAMSS_CSID_CORE_CTRL_1 0x008
#define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010)
#define CAMSS_CSID_CID_LUT_VC_n(v, n) \
(((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
#define CAMSS_CSID_CID_n_CFG(v, n) \
(((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
#define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064)
#define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068)
#define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c)
#define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
#define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
#define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \
(((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
#define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \
(((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
#define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \
(((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12
#define DATA_TYPE_YUV422_8BIT 0x1e
#define DATA_TYPE_RAW_6BIT 0x28
#define DATA_TYPE_RAW_8BIT 0x2a
#define DATA_TYPE_RAW_10BIT 0x2b
#define DATA_TYPE_RAW_12BIT 0x2c
#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0
#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
#define CSID_RESET_TIMEOUT_MS 500
struct csid_format {
u32 code;
u8 data_type;
u8 decode_format;
u8 bpp;
u8 spp; /* bus samples per pixel */
};
static const struct csid_format csid_formats_8x16[] = {
{
MEDIA_BUS_FMT_UYVY8_2X8,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
MEDIA_BUS_FMT_VYUY8_2X8,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
MEDIA_BUS_FMT_YUYV8_2X8,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
MEDIA_BUS_FMT_YVYU8_2X8,
DATA_TYPE_YUV422_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
2,
},
{
MEDIA_BUS_FMT_SBGGR8_1X8,
DATA_TYPE_RAW_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
1,
},
{
MEDIA_BUS_FMT_SGBRG8_1X8,
DATA_TYPE_RAW_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
1,
},
{
MEDIA_BUS_FMT_SGRBG8_1X8,
DATA_TYPE_RAW_8BIT,
DECODE_FORMAT_UNCOMPRESSED_8_BIT,
8,
1,
},
{
MEDIA_BUS_FMT_SRGGB8_1X8,
DATA_TYPE_RAW_8BIT,