linux/drivers/media/platform/nxp/imx-mipi-csis.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Samsung CSIS MIPI CSI-2 receiver driver.
 *
 * The Samsung CSIS IP is a MIPI CSI-2 receiver found in various NXP i.MX7 and
 * i.MX8 SoCs. The i.MX7 features version 3.3 of the IP, while i.MX8 features
 * version 3.6.3.
 *
 * Copyright (C) 2019 Linaro Ltd
 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
 *
 */

#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/spinlock.h>

#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-subdev.h>

#define CSIS_DRIVER_NAME

#define CSIS_PAD_SINK
#define CSIS_PAD_SOURCE
#define CSIS_PADS_NUM

#define MIPI_CSIS_DEF_PIX_WIDTH
#define MIPI_CSIS_DEF_PIX_HEIGHT

/* Register map definition */

/* CSIS version */
#define MIPI_CSIS_VERSION
#define MIPI_CSIS_VERSION_IMX7D
#define MIPI_CSIS_VERSION_IMX8MP

/* CSIS common control */
#define MIPI_CSIS_CMN_CTRL
#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW
#define MIPI_CSIS_CMN_CTRL_INTER_MODE
#define MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL
#define MIPI_CSIS_CMN_CTRL_RESET
#define MIPI_CSIS_CMN_CTRL_ENABLE

#define MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET
#define MIPI_CSIS_CMN_CTRL_LANE_NR_MASK

/* CSIS clock control */
#define MIPI_CSIS_CLK_CTRL
#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH3(x)
#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH2(x)
#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH1(x)
#define MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(x)
#define MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK
#define MIPI_CSIS_CLK_CTRL_WCLK_SRC

/* CSIS Interrupt mask */
#define MIPI_CSIS_INT_MSK
#define MIPI_CSIS_INT_MSK_EVEN_BEFORE
#define MIPI_CSIS_INT_MSK_EVEN_AFTER
#define MIPI_CSIS_INT_MSK_ODD_BEFORE
#define MIPI_CSIS_INT_MSK_ODD_AFTER
#define MIPI_CSIS_INT_MSK_FRAME_START
#define MIPI_CSIS_INT_MSK_FRAME_END
#define MIPI_CSIS_INT_MSK_ERR_SOT_HS
#define MIPI_CSIS_INT_MSK_ERR_LOST_FS
#define MIPI_CSIS_INT_MSK_ERR_LOST_FE
#define MIPI_CSIS_INT_MSK_ERR_OVER
#define MIPI_CSIS_INT_MSK_ERR_WRONG_CFG
#define MIPI_CSIS_INT_MSK_ERR_ECC
#define MIPI_CSIS_INT_MSK_ERR_CRC
#define MIPI_CSIS_INT_MSK_ERR_UNKNOWN

/* CSIS Interrupt source */
#define MIPI_CSIS_INT_SRC
#define MIPI_CSIS_INT_SRC_EVEN_BEFORE
#define MIPI_CSIS_INT_SRC_EVEN_AFTER
#define MIPI_CSIS_INT_SRC_EVEN
#define MIPI_CSIS_INT_SRC_ODD_BEFORE
#define MIPI_CSIS_INT_SRC_ODD_AFTER
#define MIPI_CSIS_INT_SRC_ODD
#define MIPI_CSIS_INT_SRC_NON_IMAGE_DATA
#define MIPI_CSIS_INT_SRC_FRAME_START
#define MIPI_CSIS_INT_SRC_FRAME_END
#define MIPI_CSIS_INT_SRC_ERR_SOT_HS
#define MIPI_CSIS_INT_SRC_ERR_LOST_FS
#define MIPI_CSIS_INT_SRC_ERR_LOST_FE
#define MIPI_CSIS_INT_SRC_ERR_OVER
#define MIPI_CSIS_INT_SRC_ERR_WRONG_CFG
#define MIPI_CSIS_INT_SRC_ERR_ECC
#define MIPI_CSIS_INT_SRC_ERR_CRC
#define MIPI_CSIS_INT_SRC_ERR_UNKNOWN
#define MIPI_CSIS_INT_SRC_ERRORS

/* D-PHY status control */
#define MIPI_CSIS_DPHY_STATUS
#define MIPI_CSIS_DPHY_STATUS_ULPS_DAT
#define MIPI_CSIS_DPHY_STATUS_STOPSTATE_DAT
#define MIPI_CSIS_DPHY_STATUS_ULPS_CLK
#define MIPI_CSIS_DPHY_STATUS_STOPSTATE_CLK

/* D-PHY common control */
#define MIPI_CSIS_DPHY_CMN_CTRL
#define MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(n)
#define MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE_MASK
#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(n)
#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE_MASK
#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_CLK
#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_DAT
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_DAT
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_CLK
#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE

/* D-PHY Master and Slave Control register Low */
#define MIPI_CSIS_DPHY_BCTRL_L
#define MIPI_CSIS_DPHY_BCTRL_L_USER_DATA_PATTERN_LOW(n)
#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_715MV
#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_724MV
#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_733MV
#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_706MV
#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_3MHZ
#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_1_5MHZ
#define MIPI_CSIS_DPHY_BCTRL_L_VREG12_EXTPWR_EN_CTL
#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_2V
#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_23V
#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_17V
#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_26V
#define MIPI_CSIS_DPHY_BCTRL_L_REG_1P2_LVL_SEL
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_80MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_100MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_120MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_140MV
#define MIPI_CSIS_DPHY_BCTRL_L_VREF_SRC_SEL
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_715MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_743MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_650MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_682MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_PULSE_REJECT
#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_0
#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_15P
#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_30P
#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_UP
#define MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_60MV
#define MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_70MV
#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_EN
#define MIPI_CSIS_DPHY_BCTRL_L_ERRCONTENTION_LP_EN
#define MIPI_CSIS_DPHY_BCTRL_L_TXTRIGGER_CLK_EN
#define MIPI_CSIS_DPHY_BCTRL_L_B_DPHYCTRL(n)

/* D-PHY Master and Slave Control register High */
#define MIPI_CSIS_DPHY_BCTRL_H
/* D-PHY Slave Control register Low */
#define MIPI_CSIS_DPHY_SCTRL_L
/* D-PHY Slave Control register High */
#define MIPI_CSIS_DPHY_SCTRL_H

/* ISP Configuration register */
#define MIPI_CSIS_ISP_CONFIG_CH(n)
#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK
#define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_SINGLE
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_QUAD
#define MIPI_CSIS_ISPCFG_PIXEL_MASK
#define MIPI_CSIS_ISPCFG_ALIGN_32BIT
#define MIPI_CSIS_ISPCFG_FMT(fmt)
#define MIPI_CSIS_ISPCFG_FMT_MASK

/* ISP Image Resolution register */
#define MIPI_CSIS_ISP_RESOL_CH(n)
#define CSIS_MAX_PIX_WIDTH
#define CSIS_MAX_PIX_HEIGHT

/* ISP SYNC register */
#define MIPI_CSIS_ISP_SYNC_CH(n)
#define MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET
#define MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET
#define MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET

/* ISP shadow registers */
#define MIPI_CSIS_SDW_CONFIG_CH(n)
#define MIPI_CSIS_SDW_RESOL_CH(n)
#define MIPI_CSIS_SDW_SYNC_CH(n)

/* Debug control register */
#define MIPI_CSIS_DBG_CTRL
#define MIPI_CSIS_DBG_INTR_MSK
#define MIPI_CSIS_DBG_INTR_MSK_DT_NOT_SUPPORT
#define MIPI_CSIS_DBG_INTR_MSK_DT_IGNORE
#define MIPI_CSIS_DBG_INTR_MSK_ERR_FRAME_SIZE
#define MIPI_CSIS_DBG_INTR_MSK_TRUNCATED_FRAME
#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FE
#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FS
#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_FALL
#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_RISE
#define MIPI_CSIS_DBG_INTR_SRC
#define MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT
#define MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE
#define MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE
#define MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME
#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FE
#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FS
#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL
#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE

#define MIPI_CSIS_FRAME_COUNTER_CH(n)

/* Non-image packet data buffers */
#define MIPI_CSIS_PKTDATA_ODD
#define MIPI_CSIS_PKTDATA_EVEN
#define MIPI_CSIS_PKTDATA_SIZE

#define DEFAULT_SCLK_CSIS_FREQ

/* MIPI CSI-2 Data Types */
#define MIPI_CSI2_DATA_TYPE_YUV420_8
#define MIPI_CSI2_DATA_TYPE_YUV420_10
#define MIPI_CSI2_DATA_TYPE_LE_YUV420_8
#define MIPI_CSI2_DATA_TYPE_CS_YUV420_8
#define MIPI_CSI2_DATA_TYPE_CS_YUV420_10
#define MIPI_CSI2_DATA_TYPE_YUV422_8
#define MIPI_CSI2_DATA_TYPE_YUV422_10
#define MIPI_CSI2_DATA_TYPE_RGB565
#define MIPI_CSI2_DATA_TYPE_RGB666
#define MIPI_CSI2_DATA_TYPE_RGB888
#define MIPI_CSI2_DATA_TYPE_RAW6
#define MIPI_CSI2_DATA_TYPE_RAW7
#define MIPI_CSI2_DATA_TYPE_RAW8
#define MIPI_CSI2_DATA_TYPE_RAW10
#define MIPI_CSI2_DATA_TYPE_RAW12
#define MIPI_CSI2_DATA_TYPE_RAW14
#define MIPI_CSI2_DATA_TYPE_USER(x)

struct mipi_csis_event {};

static const struct mipi_csis_event mipi_csis_events[] =;

#define MIPI_CSIS_NUM_EVENTS

enum mipi_csis_clk {};

static const char * const mipi_csis_clk_id[] =;

enum mipi_csis_version {};

struct mipi_csis_info {};

struct mipi_csis_device {};

/* -----------------------------------------------------------------------------
 * Format helpers
 */

struct csis_pix_format {};

static const struct csis_pix_format mipi_csis_formats[] =;

static const struct csis_pix_format *find_csis_format(u32 code)
{}

/* -----------------------------------------------------------------------------
 * Hardware configuration
 */

static inline u32 mipi_csis_read(struct mipi_csis_device *csis, u32 reg)
{}

static inline void mipi_csis_write(struct mipi_csis_device *csis, u32 reg,
				   u32 val)
{}

static void mipi_csis_enable_interrupts(struct mipi_csis_device *csis, bool on)
{}

static void mipi_csis_sw_reset(struct mipi_csis_device *csis)
{}

static void mipi_csis_system_enable(struct mipi_csis_device *csis, int on)
{}

static void __mipi_csis_set_format(struct mipi_csis_device *csis,
				   const struct v4l2_mbus_framefmt *format,
				   const struct csis_pix_format *csis_fmt)
{}

static int mipi_csis_calculate_params(struct mipi_csis_device *csis,
				      const struct csis_pix_format *csis_fmt)
{}

static void mipi_csis_set_params(struct mipi_csis_device *csis,
				 const struct v4l2_mbus_framefmt *format,
				 const struct csis_pix_format *csis_fmt)
{}

static int mipi_csis_clk_enable(struct mipi_csis_device *csis)
{}

static void mipi_csis_clk_disable(struct mipi_csis_device *csis)
{}

static int mipi_csis_clk_get(struct mipi_csis_device *csis)
{}

static void mipi_csis_start_stream(struct mipi_csis_device *csis,
				   const struct v4l2_mbus_framefmt *format,
				   const struct csis_pix_format *csis_fmt)
{}

static void mipi_csis_stop_stream(struct mipi_csis_device *csis)
{}

static void mipi_csis_queue_event_sof(struct mipi_csis_device *csis)
{}

static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id)
{}

/* -----------------------------------------------------------------------------
 * PHY regulator and reset
 */

static int mipi_csis_phy_enable(struct mipi_csis_device *csis)
{}

static int mipi_csis_phy_disable(struct mipi_csis_device *csis)
{}

static void mipi_csis_phy_reset(struct mipi_csis_device *csis)
{}

static int mipi_csis_phy_init(struct mipi_csis_device *csis)
{}

/* -----------------------------------------------------------------------------
 * Debug
 */

static void mipi_csis_clear_counters(struct mipi_csis_device *csis)
{}

static void mipi_csis_log_counters(struct mipi_csis_device *csis, bool non_errors)
{}

static int mipi_csis_dump_regs(struct mipi_csis_device *csis)
{}

static int mipi_csis_dump_regs_show(struct seq_file *m, void *private)
{}
DEFINE_SHOW_ATTRIBUTE();

static void mipi_csis_debugfs_init(struct mipi_csis_device *csis)
{}

static void mipi_csis_debugfs_exit(struct mipi_csis_device *csis)
{}

/* -----------------------------------------------------------------------------
 * V4L2 subdev operations
 */

static struct mipi_csis_device *sd_to_mipi_csis_device(struct v4l2_subdev *sdev)
{}

static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable)
{}

static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd,
				    struct v4l2_subdev_state *sd_state,
				    struct v4l2_subdev_mbus_code_enum *code)
{}

static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
			     struct v4l2_subdev_state *sd_state,
			     struct v4l2_subdev_format *sdformat)
{}

static int mipi_csis_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
				    struct v4l2_mbus_frame_desc *fd)
{}

static int mipi_csis_init_state(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state)
{}

static int mipi_csis_log_status(struct v4l2_subdev *sd)
{}

static int mipi_csis_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
				     struct v4l2_event_subscription *sub)
{}

static const struct v4l2_subdev_core_ops mipi_csis_core_ops =;

static const struct v4l2_subdev_video_ops mipi_csis_video_ops =;

static const struct v4l2_subdev_pad_ops mipi_csis_pad_ops =;

static const struct v4l2_subdev_ops mipi_csis_subdev_ops =;

static const struct v4l2_subdev_internal_ops mipi_csis_internal_ops =;

/* -----------------------------------------------------------------------------
 * Media entity operations
 */

static int mipi_csis_link_setup(struct media_entity *entity,
				const struct media_pad *local_pad,
				const struct media_pad *remote_pad, u32 flags)
{}

static const struct media_entity_operations mipi_csis_entity_ops =;

/* -----------------------------------------------------------------------------
 * Async subdev notifier
 */

static struct mipi_csis_device *
mipi_notifier_to_csis_state(struct v4l2_async_notifier *n)
{}

static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier,
				  struct v4l2_subdev *sd,
				  struct v4l2_async_connection *asd)
{}

static const struct v4l2_async_notifier_operations mipi_csis_notify_ops =;

static int mipi_csis_async_register(struct mipi_csis_device *csis)
{}

/* -----------------------------------------------------------------------------
 * Suspend/resume
 */

static int __maybe_unused mipi_csis_runtime_suspend(struct device *dev)
{}

static int __maybe_unused mipi_csis_runtime_resume(struct device *dev)
{}

static const struct dev_pm_ops mipi_csis_pm_ops =;

/* -----------------------------------------------------------------------------
 * Probe/remove & platform driver
 */

static int mipi_csis_subdev_init(struct mipi_csis_device *csis)
{}

static int mipi_csis_parse_dt(struct mipi_csis_device *csis)
{}

static int mipi_csis_probe(struct platform_device *pdev)
{}

static void mipi_csis_remove(struct platform_device *pdev)
{}

static const struct of_device_id mipi_csis_of_match[] =;
MODULE_DEVICE_TABLE(of, mipi_csis_of_match);

static struct platform_driver mipi_csis_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS();