linux/drivers/media/platform/xilinx/xilinx-csi2rxss.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Xilinx MIPI CSI-2 Rx Subsystem
 *
 * Copyright (C) 2016 - 2020 Xilinx, Inc.
 *
 * Contacts: Vishal Sagar <[email protected]>
 *
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/v4l2-subdev.h>
#include <media/media-entity.h>
#include <media/mipi-csi2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#include "xilinx-vip.h"

/* Register register map */
#define XCSI_CCR_OFFSET
#define XCSI_CCR_SOFTRESET
#define XCSI_CCR_ENABLE

#define XCSI_PCR_OFFSET
#define XCSI_PCR_MAXLANES_MASK
#define XCSI_PCR_ACTLANES_MASK

#define XCSI_CSR_OFFSET
#define XCSI_CSR_PKTCNT
#define XCSI_CSR_SPFIFOFULL
#define XCSI_CSR_SPFIFONE
#define XCSI_CSR_SLBF
#define XCSI_CSR_RIPCD

#define XCSI_GIER_OFFSET
#define XCSI_GIER_GIE

#define XCSI_ISR_OFFSET
#define XCSI_IER_OFFSET

#define XCSI_ISR_FR
#define XCSI_ISR_VCXFE
#define XCSI_ISR_WCC
#define XCSI_ISR_ILC
#define XCSI_ISR_SPFIFOF
#define XCSI_ISR_SPFIFONE
#define XCSI_ISR_SLBF
#define XCSI_ISR_STOP
#define XCSI_ISR_SOTERR
#define XCSI_ISR_SOTSYNCERR
#define XCSI_ISR_ECC2BERR
#define XCSI_ISR_ECC1BERR
#define XCSI_ISR_CRCERR
#define XCSI_ISR_DATAIDERR
#define XCSI_ISR_VC3FSYNCERR
#define XCSI_ISR_VC3FLVLERR
#define XCSI_ISR_VC2FSYNCERR
#define XCSI_ISR_VC2FLVLERR
#define XCSI_ISR_VC1FSYNCERR
#define XCSI_ISR_VC1FLVLERR
#define XCSI_ISR_VC0FSYNCERR
#define XCSI_ISR_VC0FLVLERR

#define XCSI_ISR_ALLINTR_MASK

/*
 * Removed VCXFE mask as it doesn't exist in IER
 * Removed STOP state irq as this will keep driver in irq handler only
 */
#define XCSI_IER_INTR_MASK

#define XCSI_SPKTR_OFFSET
#define XCSI_SPKTR_DATA
#define XCSI_SPKTR_VC
#define XCSI_SPKTR_DT
#define XCSI_SPKT_FIFO_DEPTH

#define XCSI_VCXR_OFFSET
#define XCSI_VCXR_VCERR
#define XCSI_VCXR_FSYNCERR
#define XCSI_VCXR_FLVLERR

#define XCSI_CLKINFR_OFFSET
#define XCSI_CLKINFR_STOP

#define XCSI_DLXINFR_OFFSET
#define XCSI_DLXINFR_STOP
#define XCSI_DLXINFR_SOTERR
#define XCSI_DLXINFR_SOTSYNCERR
#define XCSI_MAXDL_COUNT

#define XCSI_VCXINF1R_OFFSET
#define XCSI_VCXINF1R_LINECOUNT
#define XCSI_VCXINF1R_LINECOUNT_SHIFT
#define XCSI_VCXINF1R_BYTECOUNT

#define XCSI_VCXINF2R_OFFSET
#define XCSI_VCXINF2R_DT
#define XCSI_MAXVCX_COUNT

/*
 * Sink pad connected to sensor source pad.
 * Source pad connected to next module like demosaic.
 */
#define XCSI_MEDIA_PADS
#define XCSI_DEFAULT_WIDTH
#define XCSI_DEFAULT_HEIGHT

#define XCSI_VCX_START
#define XCSI_MAX_VC
#define XCSI_MAX_VCX

#define XCSI_NEXTREG_OFFSET

/* There are 2 events frame sync and frame level error per VC */
#define XCSI_VCX_NUM_EVENTS

/**
 * struct xcsi2rxss_event - Event log structure
 * @mask: Event mask
 * @name: Name of the event
 */
struct xcsi2rxss_event {};

static const struct xcsi2rxss_event xcsi2rxss_events[] =;

#define XCSI_NUM_EVENTS

/*
 * This table provides a mapping between CSI-2 Data type
 * and media bus formats
 */
static const u32 xcsi2dt_mbus_lut[][2] =;

/**
 * struct xcsi2rxss_state - CSI-2 Rx Subsystem device structure
 * @subdev: The v4l2 subdev structure
 * @format: Active V4L2 formats on each pad
 * @default_format: Default V4L2 format
 * @events: counter for events
 * @vcx_events: counter for vcx_events
 * @dev: Platform structure
 * @rsubdev: Remote subdev connected to sink pad
 * @rst_gpio: reset to video_aresetn
 * @clks: array of clocks
 * @iomem: Base address of subsystem
 * @max_num_lanes: Maximum number of lanes present
 * @datatype: Data type filter
 * @lock: mutex for accessing this structure
 * @pads: media pads
 * @streaming: Flag for storing streaming state
 * @enable_active_lanes: If number of active lanes can be modified
 * @en_vcx: If more than 4 VC are enabled
 *
 * This structure contains the device driver related parameters
 */
struct xcsi2rxss_state {};

static const struct clk_bulk_data xcsi2rxss_clks[] =;

static inline struct xcsi2rxss_state *
to_xcsi2rxssstate(struct v4l2_subdev *subdev)
{}

/*
 * Register related operations
 */
static inline u32 xcsi2rxss_read(struct xcsi2rxss_state *xcsi2rxss, u32 addr)
{}

static inline void xcsi2rxss_write(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
				   u32 value)
{}

static inline void xcsi2rxss_clr(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
				 u32 clr)
{}

static inline void xcsi2rxss_set(struct xcsi2rxss_state *xcsi2rxss, u32 addr,
				 u32 set)
{}

/*
 * This function returns the nth mbus for a data type.
 * In case of error, mbus code returned is 0.
 */
static u32 xcsi2rxss_get_nth_mbus(u32 dt, u32 n)
{}

/* This returns the data type for a media bus format else 0 */
static u32 xcsi2rxss_get_dt(u32 mbus)
{}

/**
 * xcsi2rxss_soft_reset - Does a soft reset of the MIPI CSI-2 Rx Subsystem
 * @state: Xilinx CSI-2 Rx Subsystem structure pointer
 *
 * Core takes less than 100 video clock cycles to reset.
 * So a larger timeout value is chosen for margin.
 *
 * Return: 0 - on success OR -ETIME if reset times out
 */
static int xcsi2rxss_soft_reset(struct xcsi2rxss_state *state)
{}

static void xcsi2rxss_hard_reset(struct xcsi2rxss_state *state)
{}

static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
{}

/* Print event counters */
static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
{}

static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
{}

static struct v4l2_subdev *xcsi2rxss_get_remote_subdev(struct media_pad *local)
{}

static int xcsi2rxss_start_stream(struct xcsi2rxss_state *state)
{}

static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *state)
{}

/**
 * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
 * @irq: IRQ number
 * @data: Pointer to device state
 *
 * In the interrupt handler, a list of event counters are updated for
 * corresponding interrupts. This is useful to get status / debug.
 *
 * Return: IRQ_HANDLED after handling interrupts
 */
static irqreturn_t xcsi2rxss_irq_handler(int irq, void *data)
{}

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

static struct v4l2_mbus_framefmt *
__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
			   struct v4l2_subdev_state *sd_state,
			   unsigned int pad, u32 which)
{}

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

static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_format *fmt)
{}

static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_format *fmt)
{}

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

/* -----------------------------------------------------------------------------
 * Media Operations
 */

static const struct media_entity_operations xcsi2rxss_media_ops =;

static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops =;

static const struct v4l2_subdev_video_ops xcsi2rxss_video_ops =;

static const struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops =;

static const struct v4l2_subdev_ops xcsi2rxss_ops =;

static const struct v4l2_subdev_internal_ops xcsi2rxss_internal_ops =;

static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
{}

static int xcsi2rxss_probe(struct platform_device *pdev)
{}

static void xcsi2rxss_remove(struct platform_device *pdev)
{}

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

static struct platform_driver xcsi2rxss_driver =;

module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();