linux/drivers/gpu/drm/bridge/tc358767.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * TC358767/TC358867/TC9595 DSI/DPI-to-DPI/(e)DP bridge driver
 *
 * The TC358767/TC358867/TC9595 can operate in multiple modes.
 * All modes are supported -- DPI->(e)DP / DSI->DPI / DSI->(e)DP .
 *
 * Copyright (C) 2016 CogentEmbedded Inc
 * Author: Andrey Gusakov <[email protected]>
 *
 * Copyright (C) 2016 Pengutronix, Philipp Zabel <[email protected]>
 *
 * Copyright (C) 2016 Zodiac Inflight Innovations
 *
 * Initially based on: drivers/gpu/drm/i2c/tda998x_drv.c
 *
 * Copyright (C) 2012 Texas Instruments
 * Author: Rob Clark <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>

/* Registers */

/* DSI D-PHY Layer registers */
#define D0W_DPHYCONTTX
#define CLW_DPHYCONTTX
#define D0W_DPHYCONTRX
#define D1W_DPHYCONTRX
#define D2W_DPHYCONTRX
#define D3W_DPHYCONTRX
#define COM_DPHYCONTRX
#define CLW_CNTRL
#define D0W_CNTRL
#define D1W_CNTRL
#define D2W_CNTRL
#define D3W_CNTRL
#define TESTMODE_CNTRL

/* PPI layer registers */
#define PPI_STARTPPI
#define PPI_BUSYPPI
#define PPI_LPTXTIMECNT
#define LPX_PERIOD
#define PPI_LANEENABLE
#define PPI_TX_RX_TA
#define TTA_GET
#define TTA_SURE
#define PPI_D0S_ATMR
#define PPI_D1S_ATMR
#define PPI_D0S_CLRSIPOCOUNT
#define PPI_D1S_CLRSIPOCOUNT
#define PPI_D2S_CLRSIPOCOUNT
#define PPI_D3S_CLRSIPOCOUNT
#define PPI_START_FUNCTION

/* DSI layer registers */
#define DSI_STARTDSI
#define DSI_BUSYDSI
#define DSI_LANEENABLE
#define DSI_RX_START

/* Lane enable PPI and DSI register bits */
#define LANEENABLE_CLEN
#define LANEENABLE_L0EN
#define LANEENABLE_L1EN
#define LANEENABLE_L2EN
#define LANEENABLE_L3EN

#define DSI_LANESTATUS0
#define DSI_LANESTATUS1
#define DSI_INTSTATUS
#define DSI_INTMASK
#define DSI_INTCLR
#define DSI_LPTXTO

/* DSI General Registers */
#define DSIERRCNT

/* DSI Application Layer Registers */
#define APLCTRL
#define RDPKTLN

/* Display Parallel Input Interface */
#define DPIPXLFMT
#define VS_POL_ACTIVE_LOW
#define HS_POL_ACTIVE_LOW
#define DE_POL_ACTIVE_HIGH
#define SUB_CFG_TYPE_CONFIG1
#define SUB_CFG_TYPE_CONFIG2
#define SUB_CFG_TYPE_CONFIG3
#define DPI_BPP_RGB888
#define DPI_BPP_RGB666
#define DPI_BPP_RGB565

/* Display Parallel Output Interface */
#define POCTRL
#define POCTRL_S2P
#define POCTRL_PCLK_POL
#define POCTRL_VS_POL
#define POCTRL_HS_POL
#define POCTRL_DE_POL

/* Video Path */
#define VPCTRL0
#define VSDELAY
#define OPXLFMT_RGB666
#define OPXLFMT_RGB888
#define FRMSYNC_DISABLED
#define FRMSYNC_ENABLED
#define MSF_DISABLED
#define MSF_ENABLED
#define HTIM01
#define HPW
#define HBPR
#define HTIM02
#define HDISPR
#define HFPR
#define VTIM01
#define VSPR
#define VBPR
#define VTIM02
#define VFPR
#define VDISPR
#define VFUEN0
#define VFUEN

/* System */
#define TC_IDREG
#define SYSBOOT
#define SYSSTAT
#define SYSRSTENB
#define ENBI2C
#define ENBLCD0
#define ENBBM
#define ENBDSIRX
#define ENBREG
#define ENBHDCP
#define SYSCTRL
#define DP0_AUDSRC_NO_INPUT
#define DP0_AUDSRC_I2S_RX
#define DP0_VIDSRC_NO_INPUT
#define DP0_VIDSRC_DSI_RX
#define DP0_VIDSRC_DPI_RX
#define DP0_VIDSRC_COLOR_BAR
#define GPIOM
#define GPIOC
#define GPIOO
#define GPIOI
#define INTCTL_G
#define INTSTS_G

#define INT_SYSERR
#define INT_GPIO_H(x)
#define INT_GPIO_LC(x)

#define TEST_INT_C
#define TEST_INT_S

#define INT_GP0_LCNT
#define INT_GP1_LCNT

/* Control */
#define DP0CTL
#define VID_MN_GEN
#define EF_EN
#define VID_EN
#define DP_EN

/* Clocks */
#define DP0_VIDMNGEN0
#define DP0_VIDMNGEN1
#define DP0_VMNGENSTATUS
#define DP0_AUDMNGEN0
#define DP0_AUDMNGEN1
#define DP0_AMNGENSTATUS

/* Main Channel */
#define DP0_SECSAMPLE
#define DP0_VIDSYNCDELAY
#define VID_SYNC_DLY
#define THRESH_DLY

#define DP0_TOTALVAL
#define H_TOTAL
#define V_TOTAL
#define DP0_STARTVAL
#define H_START
#define V_START
#define DP0_ACTIVEVAL
#define H_ACT
#define V_ACT

#define DP0_SYNCVAL
#define VS_WIDTH
#define HS_WIDTH
#define SYNCVAL_HS_POL_ACTIVE_LOW
#define SYNCVAL_VS_POL_ACTIVE_LOW
#define DP0_MISC
#define TU_SIZE_RECOMMENDED
#define MAX_TU_SYMBOL
#define TU_SIZE
#define BPC_6
#define BPC_8

/* AUX channel */
#define DP0_AUXCFG0
#define DP0_AUXCFG0_BSIZE
#define DP0_AUXCFG0_ADDR_ONLY
#define DP0_AUXCFG1
#define AUX_RX_FILTER_EN

#define DP0_AUXADDR
#define DP0_AUXWDATA(i)
#define DP0_AUXRDATA(i)
#define DP0_AUXSTATUS
#define AUX_BYTES
#define AUX_STATUS
#define AUX_TIMEOUT
#define AUX_BUSY
#define DP0_AUXI2CADR

/* Link Training */
#define DP0_SRCCTRL
#define DP0_SRCCTRL_SCRMBLDIS
#define DP0_SRCCTRL_EN810B
#define DP0_SRCCTRL_NOTP
#define DP0_SRCCTRL_TP1
#define DP0_SRCCTRL_TP2
#define DP0_SRCCTRL_LANESKEW
#define DP0_SRCCTRL_SSCG
#define DP0_SRCCTRL_LANES_1
#define DP0_SRCCTRL_LANES_2
#define DP0_SRCCTRL_BW27
#define DP0_SRCCTRL_BW162
#define DP0_SRCCTRL_AUTOCORRECT
#define DP0_LTSTAT
#define LT_LOOPDONE
#define LT_STATUS_MASK
#define LT_CHANNEL1_EQ_BITS
#define LT_INTERLANE_ALIGN_DONE
#define LT_CHANNEL0_EQ_BITS
#define DP0_SNKLTCHGREQ
#define DP0_LTLOOPCTRL
#define DP0_SNKLTCTRL
#define DP0_TPATDAT0
#define DP0_TPATDAT1
#define DP0_TPATDAT2
#define DP0_TPATDAT3

#define AUDCFG0
#define AUDCFG1
#define AUDIFDATA0
#define AUDIFDATA1
#define AUDIFDATA2
#define AUDIFDATA3
#define AUDIFDATA4
#define AUDIFDATA5
#define AUDIFDATA6

#define DP1_SRCCTRL

/* PHY */
#define DP_PHY_CTRL
#define DP_PHY_RST
#define BGREN
#define PWR_SW_EN
#define PHY_M1_RST
#define PHY_RDY
#define PHY_M0_RST
#define PHY_2LANE
#define PHY_A0_EN
#define PHY_M0_EN
#define DP_PHY_CFG_WR
#define DP_PHY_CFG_RD
#define DP0_AUX_PHY_CTRL
#define DP0_MAIN_PHY_DBG

/* I2S */
#define I2SCFG
#define I2SCH0STAT0
#define I2SCH0STAT1
#define I2SCH0STAT2
#define I2SCH0STAT3
#define I2SCH0STAT4
#define I2SCH0STAT5
#define I2SCH1STAT0
#define I2SCH1STAT1
#define I2SCH1STAT2
#define I2SCH1STAT3
#define I2SCH1STAT4
#define I2SCH1STAT5

/* PLL */
#define DP0_PLLCTRL
#define DP1_PLLCTRL
#define PXL_PLLCTRL
#define PLLUPDATE
#define PLLBYP
#define PLLEN
#define PXL_PLLPARAM
#define IN_SEL_REFCLK
#define SYS_PLLPARAM
#define REF_FREQ_38M4
#define REF_FREQ_19M2
#define REF_FREQ_26M
#define REF_FREQ_13M
#define SYSCLK_SEL_LSCLK
#define LSCLK_DIV_1
#define LSCLK_DIV_2

/* Test & Debug */
#define TSTCTL
#define COLOR_R
#define COLOR_G
#define COLOR_B
#define ENI2CFILTER
#define COLOR_BAR_MODE
#define COLOR_BAR_MODE_BARS
#define PLL_DBG

static bool tc_test_pattern;
module_param_named(test, tc_test_pattern, bool, 0644);

struct tc_edp_link {};

struct tc_data {};

static inline struct tc_data *aux_to_tc(struct drm_dp_aux *a)
{}

static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
{}

static inline struct tc_data *connector_to_tc(struct drm_connector *c)
{}

static inline int tc_poll_timeout(struct tc_data *tc, unsigned int addr,
				  unsigned int cond_mask,
				  unsigned int cond_value,
				  unsigned long sleep_us, u64 timeout_us)
{}

static int tc_aux_wait_busy(struct tc_data *tc)
{}

static int tc_aux_write_data(struct tc_data *tc, const void *data,
			     size_t size)
{}

static int tc_aux_read_data(struct tc_data *tc, void *data, size_t size)
{}

static u32 tc_auxcfg0(struct drm_dp_aux_msg *msg, size_t size)
{}

static ssize_t tc_aux_transfer(struct drm_dp_aux *aux,
			       struct drm_dp_aux_msg *msg)
{}

static const char * const training_pattern1_errors[] =;

static const char * const training_pattern2_errors[] =;

static u32 tc_srcctrl(struct tc_data *tc)
{}

static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl)
{}

static int tc_pxl_pll_calc(struct tc_data *tc, u32 refclk, u32 pixelclock,
			   int *out_best_pixelclock, u32 *out_pxl_pllparam)
{}

static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
{}

static int tc_pxl_pll_dis(struct tc_data *tc)
{}

static int tc_stream_clock_calc(struct tc_data *tc)
{}

static int tc_set_syspllparam(struct tc_data *tc)
{}

static int tc_aux_link_setup(struct tc_data *tc)
{}

static int tc_get_display_props(struct tc_data *tc)
{}

static int tc_set_common_video_mode(struct tc_data *tc,
				    const struct drm_display_mode *mode)
{}

static int tc_set_dpi_video_mode(struct tc_data *tc,
				 const struct drm_display_mode *mode)
{}

static int tc_set_edp_video_mode(struct tc_data *tc,
				 const struct drm_display_mode *mode)
{}

static int tc_wait_link_training(struct tc_data *tc)
{}

static int tc_main_link_enable(struct tc_data *tc)
{}

static int tc_main_link_disable(struct tc_data *tc)
{}

static int tc_dsi_rx_enable(struct tc_data *tc)
{}

static int tc_dpi_rx_enable(struct tc_data *tc)
{}

static int tc_dpi_stream_enable(struct tc_data *tc)
{}

static int tc_dpi_stream_disable(struct tc_data *tc)
{}

static int tc_edp_stream_enable(struct tc_data *tc)
{}

static int tc_edp_stream_disable(struct tc_data *tc)
{}

static void
tc_dpi_bridge_atomic_enable(struct drm_bridge *bridge,
			    struct drm_bridge_state *old_bridge_state)

{}

static void
tc_dpi_bridge_atomic_disable(struct drm_bridge *bridge,
			     struct drm_bridge_state *old_bridge_state)
{}

static void
tc_edp_bridge_atomic_enable(struct drm_bridge *bridge,
			    struct drm_bridge_state *old_bridge_state)
{}

static void
tc_edp_bridge_atomic_disable(struct drm_bridge *bridge,
			     struct drm_bridge_state *old_bridge_state)
{}

static int tc_dpi_atomic_check(struct drm_bridge *bridge,
			       struct drm_bridge_state *bridge_state,
			       struct drm_crtc_state *crtc_state,
			       struct drm_connector_state *conn_state)
{}

static int tc_edp_atomic_check(struct drm_bridge *bridge,
			       struct drm_bridge_state *bridge_state,
			       struct drm_crtc_state *crtc_state,
			       struct drm_connector_state *conn_state)
{}

static enum drm_mode_status
tc_dpi_mode_valid(struct drm_bridge *bridge,
		  const struct drm_display_info *info,
		  const struct drm_display_mode *mode)
{}

static enum drm_mode_status
tc_edp_mode_valid(struct drm_bridge *bridge,
		  const struct drm_display_info *info,
		  const struct drm_display_mode *mode)
{}

static void tc_bridge_mode_set(struct drm_bridge *bridge,
			       const struct drm_display_mode *mode,
			       const struct drm_display_mode *adj)
{}

static const struct drm_edid *tc_edid_read(struct drm_bridge *bridge,
					   struct drm_connector *connector)
{}

static int tc_connector_get_modes(struct drm_connector *connector)
{}

static const struct drm_connector_helper_funcs tc_connector_helper_funcs =;

static enum drm_connector_status tc_bridge_detect(struct drm_bridge *bridge)
{}

static enum drm_connector_status
tc_connector_detect(struct drm_connector *connector, bool force)
{}

static const struct drm_connector_funcs tc_connector_funcs =;

static int tc_dpi_bridge_attach(struct drm_bridge *bridge,
				enum drm_bridge_attach_flags flags)
{}

static int tc_edp_bridge_attach(struct drm_bridge *bridge,
				enum drm_bridge_attach_flags flags)
{}

static void tc_edp_bridge_detach(struct drm_bridge *bridge)
{}

#define MAX_INPUT_SEL_FORMATS
#define MAX_OUTPUT_SEL_FORMATS

static u32 *
tc_dpi_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
				 struct drm_bridge_state *bridge_state,
				 struct drm_crtc_state *crtc_state,
				 struct drm_connector_state *conn_state,
				 u32 output_fmt,
				 unsigned int *num_input_fmts)
{}

static u32 *
tc_edp_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
				  struct drm_bridge_state *bridge_state,
				  struct drm_crtc_state *crtc_state,
				  struct drm_connector_state *conn_state,
				  unsigned int *num_output_fmts)
{}

static const struct drm_bridge_funcs tc_dpi_bridge_funcs =;

static const struct drm_bridge_funcs tc_edp_bridge_funcs =;

static bool tc_readable_reg(struct device *dev, unsigned int reg)
{}

static const struct regmap_range tc_volatile_ranges[] =;

static const struct regmap_access_table tc_volatile_table =;

static const struct regmap_range tc_precious_ranges[] =;

static const struct regmap_access_table tc_precious_table =;

static const struct regmap_range tc_non_writeable_ranges[] =;

static const struct regmap_access_table tc_writeable_table =;

static const struct regmap_config tc_regmap_config =;

static irqreturn_t tc_irq_handler(int irq, void *arg)
{}

static int tc_mipi_dsi_host_attach(struct tc_data *tc)
{}

static int tc_probe_dpi_bridge_endpoint(struct tc_data *tc)
{}

static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
{}

static int tc_probe_bridge_endpoint(struct tc_data *tc)
{}

static int tc_probe(struct i2c_client *client)
{}

static void tc_remove(struct i2c_client *client)
{}

static const struct i2c_device_id tc358767_i2c_ids[] =;
MODULE_DEVICE_TABLE(i2c, tc358767_i2c_ids);

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

static struct i2c_driver tc358767_driver =;
module_i2c_driver();

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