linux/drivers/gpu/drm/vc4/vc4_dsi.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2016 Broadcom
 */

/**
 * DOC: VC4 DSI0/DSI1 module
 *
 * BCM2835 contains two DSI modules, DSI0 and DSI1.  DSI0 is a
 * single-lane DSI controller, while DSI1 is a more modern 4-lane DSI
 * controller.
 *
 * Most Raspberry Pi boards expose DSI1 as their "DISPLAY" connector,
 * while the compute module brings both DSI0 and DSI1 out.
 *
 * This driver has been tested for DSI1 video-mode display only
 * currently, with most of the information necessary for DSI0
 * hopefully present.
 */

#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/component.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.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_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>

#include "vc4_drv.h"
#include "vc4_regs.h"

#define DSI_CMD_FIFO_DEPTH
#define DSI_PIX_FIFO_DEPTH
#define DSI_PIX_FIFO_WIDTH

#define DSI0_CTRL

/* Command packet control. */
#define DSI0_TXPKT1C
#define DSI1_TXPKT1C
#define DSI_TXPKT1C_TRIG_CMD_MASK
#define DSI_TXPKT1C_TRIG_CMD_SHIFT
#define DSI_TXPKT1C_CMD_REPEAT_MASK
#define DSI_TXPKT1C_CMD_REPEAT_SHIFT

#define DSI_TXPKT1C_DISPLAY_NO_MASK
#define DSI_TXPKT1C_DISPLAY_NO_SHIFT
/* Short, trigger, BTA, or a long packet that fits all in CMDFIFO. */
#define DSI_TXPKT1C_DISPLAY_NO_SHORT
/* Primary display where cmdfifo provides part of the payload and
 * pixelvalve the rest.
 */
#define DSI_TXPKT1C_DISPLAY_NO_PRIMARY
/* Secondary display where cmdfifo provides part of the payload and
 * pixfifo the rest.
 */
#define DSI_TXPKT1C_DISPLAY_NO_SECONDARY

#define DSI_TXPKT1C_CMD_TX_TIME_MASK
#define DSI_TXPKT1C_CMD_TX_TIME_SHIFT

#define DSI_TXPKT1C_CMD_CTRL_MASK
#define DSI_TXPKT1C_CMD_CTRL_SHIFT
/* Command only.  Uses TXPKT1H and DISPLAY_NO */
#define DSI_TXPKT1C_CMD_CTRL_TX
/* Command with BTA for either ack or read data. */
#define DSI_TXPKT1C_CMD_CTRL_RX
/* Trigger according to TRIG_CMD */
#define DSI_TXPKT1C_CMD_CTRL_TRIG
/* BTA alone for getting error status after a command, or a TE trigger
 * without a previous command.
 */
#define DSI_TXPKT1C_CMD_CTRL_BTA

#define DSI_TXPKT1C_CMD_MODE_LP
#define DSI_TXPKT1C_CMD_TYPE_LONG
#define DSI_TXPKT1C_CMD_TE_EN
#define DSI_TXPKT1C_CMD_EN

/* Command packet header. */
#define DSI0_TXPKT1H
#define DSI1_TXPKT1H
#define DSI_TXPKT1H_BC_CMDFIFO_MASK
#define DSI_TXPKT1H_BC_CMDFIFO_SHIFT
#define DSI_TXPKT1H_BC_PARAM_MASK
#define DSI_TXPKT1H_BC_PARAM_SHIFT
#define DSI_TXPKT1H_BC_DT_MASK
#define DSI_TXPKT1H_BC_DT_SHIFT

#define DSI0_RXPKT1H
#define DSI1_RXPKT1H
#define DSI_RXPKT1H_CRC_ERR
#define DSI_RXPKT1H_DET_ERR
#define DSI_RXPKT1H_ECC_ERR
#define DSI_RXPKT1H_COR_ERR
#define DSI_RXPKT1H_INCOMP_PKT
#define DSI_RXPKT1H_PKT_TYPE_LONG
/* Byte count if DSI_RXPKT1H_PKT_TYPE_LONG */
#define DSI_RXPKT1H_BC_PARAM_MASK
#define DSI_RXPKT1H_BC_PARAM_SHIFT
/* Short return bytes if !DSI_RXPKT1H_PKT_TYPE_LONG */
#define DSI_RXPKT1H_SHORT_1_MASK
#define DSI_RXPKT1H_SHORT_1_SHIFT
#define DSI_RXPKT1H_SHORT_0_MASK
#define DSI_RXPKT1H_SHORT_0_SHIFT
#define DSI_RXPKT1H_DT_LP_CMD_MASK
#define DSI_RXPKT1H_DT_LP_CMD_SHIFT

#define DSI0_RXPKT2H
#define DSI1_RXPKT2H
#define DSI_RXPKT1H_DET_ERR
#define DSI_RXPKT1H_ECC_ERR
#define DSI_RXPKT1H_COR_ERR
#define DSI_RXPKT1H_INCOMP_PKT
#define DSI_RXPKT1H_BC_PARAM_MASK
#define DSI_RXPKT1H_BC_PARAM_SHIFT
#define DSI_RXPKT1H_DT_MASK
#define DSI_RXPKT1H_DT_SHIFT

#define DSI0_TXPKT_CMD_FIFO
#define DSI1_TXPKT_CMD_FIFO

#define DSI0_DISP0_CTRL
#define DSI_DISP0_PIX_CLK_DIV_MASK
#define DSI_DISP0_PIX_CLK_DIV_SHIFT
#define DSI_DISP0_LP_STOP_CTRL_MASK
#define DSI_DISP0_LP_STOP_CTRL_SHIFT
#define DSI_DISP0_LP_STOP_DISABLE
#define DSI_DISP0_LP_STOP_PERLINE
#define DSI_DISP0_LP_STOP_PERFRAME

/* Transmit RGB pixels and null packets only during HACTIVE, instead
 * of going to LP-STOP.
 */
#define DSI_DISP_HACTIVE_NULL
/* Transmit blanking packet only during vblank, instead of allowing LP-STOP. */
#define DSI_DISP_VBLP_CTRL
/* Transmit blanking packet only during HFP, instead of allowing LP-STOP. */
#define DSI_DISP_HFP_CTRL
/* Transmit blanking packet only during HBP, instead of allowing LP-STOP. */
#define DSI_DISP_HBP_CTRL
#define DSI_DISP0_CHANNEL_MASK
#define DSI_DISP0_CHANNEL_SHIFT
/* Enables end events for HSYNC/VSYNC, not just start events. */
#define DSI_DISP0_ST_END
#define DSI_DISP0_PFORMAT_MASK
#define DSI_DISP0_PFORMAT_SHIFT
#define DSI_PFORMAT_RGB565
#define DSI_PFORMAT_RGB666_PACKED
#define DSI_PFORMAT_RGB666
#define DSI_PFORMAT_RGB888
/* Default is VIDEO mode. */
#define DSI_DISP0_COMMAND_MODE
#define DSI_DISP0_ENABLE

#define DSI0_DISP1_CTRL
#define DSI1_DISP1_CTRL
/* Format of the data written to TXPKT_PIX_FIFO. */
#define DSI_DISP1_PFORMAT_MASK
#define DSI_DISP1_PFORMAT_SHIFT
#define DSI_DISP1_PFORMAT_16BIT
#define DSI_DISP1_PFORMAT_24BIT
#define DSI_DISP1_PFORMAT_32BIT_LE
#define DSI_DISP1_PFORMAT_32BIT_BE

/* DISP1 is always command mode. */
#define DSI_DISP1_ENABLE

#define DSI0_TXPKT_PIX_FIFO

#define DSI0_INT_STAT
#define DSI0_INT_EN
#define DSI0_INT_FIFO_ERR
#define DSI0_INT_CMDC_DONE_MASK
#define DSI0_INT_CMDC_DONE_SHIFT
#define DSI0_INT_CMDC_DONE_NO_REPEAT
#define DSI0_INT_CMDC_DONE_REPEAT
#define DSI0_INT_PHY_DIR_RTF
#define DSI0_INT_PHY_D1_ULPS
#define DSI0_INT_PHY_D1_STOP
#define DSI0_INT_PHY_RXLPDT
#define DSI0_INT_PHY_RXTRIG
#define DSI0_INT_PHY_D0_ULPS
#define DSI0_INT_PHY_D0_LPDT
#define DSI0_INT_PHY_D0_FTR
#define DSI0_INT_PHY_D0_STOP
/* Signaled when the clock lane enters the given state. */
#define DSI0_INT_PHY_CLK_ULPS
#define DSI0_INT_PHY_CLK_HS
#define DSI0_INT_PHY_CLK_FTR
/* Signaled on timeouts */
#define DSI0_INT_PR_TO
#define DSI0_INT_TA_TO
#define DSI0_INT_LPRX_TO
#define DSI0_INT_HSTX_TO
/* Contention on a line when trying to drive the line low */
#define DSI0_INT_ERR_CONT_LP1
#define DSI0_INT_ERR_CONT_LP0
/* Control error: incorrect line state sequence on data lane 0. */
#define DSI0_INT_ERR_CONTROL
#define DSI0_INT_ERR_SYNC_ESC
#define DSI0_INT_RX2_PKT
#define DSI0_INT_RX1_PKT
#define DSI0_INT_CMD_PKT

#define DSI0_INTERRUPTS_ALWAYS_ENABLED

#define DSI1_INT_PHY_D3_ULPS
#define DSI1_INT_PHY_D3_STOP
#define DSI1_INT_PHY_D2_ULPS
#define DSI1_INT_PHY_D2_STOP
#define DSI1_INT_PHY_D1_ULPS
#define DSI1_INT_PHY_D1_STOP
#define DSI1_INT_PHY_D0_ULPS
#define DSI1_INT_PHY_D0_STOP
#define DSI1_INT_FIFO_ERR
#define DSI1_INT_PHY_DIR_RTF
#define DSI1_INT_PHY_RXLPDT
#define DSI1_INT_PHY_RXTRIG
#define DSI1_INT_PHY_D0_LPDT
#define DSI1_INT_PHY_DIR_FTR

/* Signaled when the clock lane enters the given state. */
#define DSI1_INT_PHY_CLOCK_ULPS
#define DSI1_INT_PHY_CLOCK_HS
#define DSI1_INT_PHY_CLOCK_STOP

/* Signaled on timeouts */
#define DSI1_INT_PR_TO
#define DSI1_INT_TA_TO
#define DSI1_INT_LPRX_TO
#define DSI1_INT_HSTX_TO

/* Contention on a line when trying to drive the line low */
#define DSI1_INT_ERR_CONT_LP1
#define DSI1_INT_ERR_CONT_LP0

/* Control error: incorrect line state sequence on data lane 0. */
#define DSI1_INT_ERR_CONTROL
/* LPDT synchronization error (bits received not a multiple of 8. */

#define DSI1_INT_ERR_SYNC_ESC
/* Signaled after receiving an error packet from the display in
 * response to a read.
 */
#define DSI1_INT_RXPKT2
/* Signaled after receiving a packet.  The header and optional short
 * response will be in RXPKT1H, and a long response will be in the
 * RXPKT_FIFO.
 */
#define DSI1_INT_RXPKT1
#define DSI1_INT_TXPKT2_DONE
#define DSI1_INT_TXPKT2_END
/* Signaled after all repeats of TXPKT1 are transferred. */
#define DSI1_INT_TXPKT1_DONE
/* Signaled after each TXPKT1 repeat is scheduled. */
#define DSI1_INT_TXPKT1_END

#define DSI1_INTERRUPTS_ALWAYS_ENABLED

#define DSI0_STAT
#define DSI0_HSTX_TO_CNT
#define DSI0_LPRX_TO_CNT
#define DSI0_TA_TO_CNT
#define DSI0_PR_TO_CNT
#define DSI0_PHYC
#define DSI1_PHYC_ESC_CLK_LPDT_MASK
#define DSI1_PHYC_ESC_CLK_LPDT_SHIFT
#define DSI1_PHYC_HS_CLK_CONTINUOUS
#define DSI0_PHYC_ESC_CLK_LPDT_MASK
#define DSI0_PHYC_ESC_CLK_LPDT_SHIFT
#define DSI1_PHYC_CLANE_ULPS
#define DSI1_PHYC_CLANE_ENABLE
#define DSI_PHYC_DLANE3_ULPS
#define DSI_PHYC_DLANE3_ENABLE
#define DSI0_PHYC_HS_CLK_CONTINUOUS
#define DSI0_PHYC_CLANE_ULPS
#define DSI_PHYC_DLANE2_ULPS
#define DSI0_PHYC_CLANE_ENABLE
#define DSI_PHYC_DLANE2_ENABLE
#define DSI_PHYC_DLANE1_ULPS
#define DSI_PHYC_DLANE1_ENABLE
#define DSI_PHYC_DLANE0_FORCE_STOP
#define DSI_PHYC_DLANE0_ULPS
#define DSI_PHYC_DLANE0_ENABLE

#define DSI0_HS_CLT0
#define DSI0_HS_CLT1
#define DSI0_HS_CLT2
#define DSI0_HS_DLT3
#define DSI0_HS_DLT4
#define DSI0_HS_DLT5
#define DSI0_HS_DLT6
#define DSI0_HS_DLT7

#define DSI0_PHY_AFEC0
#define DSI0_PHY_AFEC0_DDR2CLK_EN
#define DSI0_PHY_AFEC0_DDRCLK_EN
#define DSI0_PHY_AFEC0_LATCH_ULPS
#define DSI1_PHY_AFEC0_IDR_DLANE3_MASK
#define DSI1_PHY_AFEC0_IDR_DLANE3_SHIFT
#define DSI1_PHY_AFEC0_IDR_DLANE2_MASK
#define DSI1_PHY_AFEC0_IDR_DLANE2_SHIFT
#define DSI1_PHY_AFEC0_IDR_DLANE1_MASK
#define DSI1_PHY_AFEC0_IDR_DLANE1_SHIFT
#define DSI1_PHY_AFEC0_IDR_DLANE0_MASK
#define DSI1_PHY_AFEC0_IDR_DLANE0_SHIFT
#define DSI1_PHY_AFEC0_IDR_CLANE_MASK
#define DSI1_PHY_AFEC0_IDR_CLANE_SHIFT
#define DSI0_PHY_AFEC0_ACTRL_DLANE1_MASK
#define DSI0_PHY_AFEC0_ACTRL_DLANE1_SHIFT
#define DSI0_PHY_AFEC0_ACTRL_DLANE0_MASK
#define DSI0_PHY_AFEC0_ACTRL_DLANE0_SHIFT
#define DSI0_PHY_AFEC0_ACTRL_CLANE_MASK
#define DSI0_PHY_AFEC0_ACTRL_CLANE_SHIFT
#define DSI1_PHY_AFEC0_DDR2CLK_EN
#define DSI1_PHY_AFEC0_DDRCLK_EN
#define DSI1_PHY_AFEC0_LATCH_ULPS
#define DSI1_PHY_AFEC0_RESET
#define DSI1_PHY_AFEC0_PD
#define DSI0_PHY_AFEC0_RESET
#define DSI1_PHY_AFEC0_PD_BG
#define DSI0_PHY_AFEC0_PD
#define DSI1_PHY_AFEC0_PD_DLANE1
#define DSI0_PHY_AFEC0_PD_BG
#define DSI1_PHY_AFEC0_PD_DLANE2
#define DSI0_PHY_AFEC0_PD_DLANE1
#define DSI1_PHY_AFEC0_PD_DLANE3
#define DSI_PHY_AFEC0_PTATADJ_MASK
#define DSI_PHY_AFEC0_PTATADJ_SHIFT
#define DSI_PHY_AFEC0_CTATADJ_MASK
#define DSI_PHY_AFEC0_CTATADJ_SHIFT

#define DSI0_PHY_AFEC1
#define DSI0_PHY_AFEC1_IDR_DLANE1_MASK
#define DSI0_PHY_AFEC1_IDR_DLANE1_SHIFT
#define DSI0_PHY_AFEC1_IDR_DLANE0_MASK
#define DSI0_PHY_AFEC1_IDR_DLANE0_SHIFT
#define DSI0_PHY_AFEC1_IDR_CLANE_MASK
#define DSI0_PHY_AFEC1_IDR_CLANE_SHIFT

#define DSI0_TST_SEL
#define DSI0_TST_MON
#define DSI0_ID
#define DSI_ID_VALUE

#define DSI1_CTRL
#define DSI_CTRL_HS_CLKC_MASK
#define DSI_CTRL_HS_CLKC_SHIFT
#define DSI_CTRL_HS_CLKC_BYTE
#define DSI_CTRL_HS_CLKC_DDR2
#define DSI_CTRL_HS_CLKC_DDR

#define DSI_CTRL_RX_LPDT_EOT_DISABLE
#define DSI_CTRL_LPDT_EOT_DISABLE
#define DSI_CTRL_HSDT_EOT_DISABLE
#define DSI_CTRL_SOFT_RESET_CFG
#define DSI_CTRL_CAL_BYTE
#define DSI_CTRL_INV_BYTE
#define DSI_CTRL_CLR_LDF
#define DSI0_CTRL_CLR_PBCF
#define DSI1_CTRL_CLR_RXF
#define DSI0_CTRL_CLR_CPBCF
#define DSI1_CTRL_CLR_PDF
#define DSI0_CTRL_CLR_PDF
#define DSI1_CTRL_CLR_CDF
#define DSI0_CTRL_CLR_CDF
#define DSI0_CTRL_CTRL2
#define DSI1_CTRL_DISABLE_DISP_CRCC
#define DSI0_CTRL_CTRL1
#define DSI1_CTRL_DISABLE_DISP_ECCC
#define DSI0_CTRL_CTRL0
#define DSI1_CTRL_EN
#define DSI0_CTRL_RESET_FIFOS
#define DSI1_CTRL_RESET_FIFOS

#define DSI1_TXPKT2C
#define DSI1_TXPKT2H
#define DSI1_TXPKT_PIX_FIFO
#define DSI1_RXPKT_FIFO
#define DSI1_DISP0_CTRL
#define DSI1_INT_STAT
#define DSI1_INT_EN
/* State reporting bits.  These mostly behave like INT_STAT, where
 * writing a 1 clears the bit.
 */
#define DSI1_STAT
#define DSI1_STAT_PHY_D3_ULPS
#define DSI1_STAT_PHY_D3_STOP
#define DSI1_STAT_PHY_D2_ULPS
#define DSI1_STAT_PHY_D2_STOP
#define DSI1_STAT_PHY_D1_ULPS
#define DSI1_STAT_PHY_D1_STOP
#define DSI1_STAT_PHY_D0_ULPS
#define DSI1_STAT_PHY_D0_STOP
#define DSI1_STAT_FIFO_ERR
#define DSI1_STAT_PHY_RXLPDT
#define DSI1_STAT_PHY_RXTRIG
#define DSI1_STAT_PHY_D0_LPDT
/* Set when in forward direction */
#define DSI1_STAT_PHY_DIR
#define DSI1_STAT_PHY_CLOCK_ULPS
#define DSI1_STAT_PHY_CLOCK_HS
#define DSI1_STAT_PHY_CLOCK_STOP
#define DSI1_STAT_PR_TO
#define DSI1_STAT_TA_TO
#define DSI1_STAT_LPRX_TO
#define DSI1_STAT_HSTX_TO
#define DSI1_STAT_ERR_CONT_LP1
#define DSI1_STAT_ERR_CONT_LP0
#define DSI1_STAT_ERR_CONTROL
#define DSI1_STAT_ERR_SYNC_ESC
#define DSI1_STAT_RXPKT2
#define DSI1_STAT_RXPKT1
#define DSI1_STAT_TXPKT2_BUSY
#define DSI1_STAT_TXPKT2_DONE
#define DSI1_STAT_TXPKT2_END
#define DSI1_STAT_TXPKT1_BUSY
#define DSI1_STAT_TXPKT1_DONE
#define DSI1_STAT_TXPKT1_END

#define DSI1_HSTX_TO_CNT
#define DSI1_LPRX_TO_CNT
#define DSI1_TA_TO_CNT
#define DSI1_PR_TO_CNT
#define DSI1_PHYC

#define DSI1_HS_CLT0
#define DSI_HS_CLT0_CZERO_MASK
#define DSI_HS_CLT0_CZERO_SHIFT
#define DSI_HS_CLT0_CPRE_MASK
#define DSI_HS_CLT0_CPRE_SHIFT
#define DSI_HS_CLT0_CPREP_MASK
#define DSI_HS_CLT0_CPREP_SHIFT

#define DSI1_HS_CLT1
#define DSI_HS_CLT1_CTRAIL_MASK
#define DSI_HS_CLT1_CTRAIL_SHIFT
#define DSI_HS_CLT1_CPOST_MASK
#define DSI_HS_CLT1_CPOST_SHIFT

#define DSI1_HS_CLT2
#define DSI_HS_CLT2_WUP_MASK
#define DSI_HS_CLT2_WUP_SHIFT

#define DSI1_HS_DLT3
#define DSI_HS_DLT3_EXIT_MASK
#define DSI_HS_DLT3_EXIT_SHIFT
#define DSI_HS_DLT3_ZERO_MASK
#define DSI_HS_DLT3_ZERO_SHIFT
#define DSI_HS_DLT3_PRE_MASK
#define DSI_HS_DLT3_PRE_SHIFT

#define DSI1_HS_DLT4
#define DSI_HS_DLT4_ANLAT_MASK
#define DSI_HS_DLT4_ANLAT_SHIFT
#define DSI_HS_DLT4_TRAIL_MASK
#define DSI_HS_DLT4_TRAIL_SHIFT
#define DSI_HS_DLT4_LPX_MASK
#define DSI_HS_DLT4_LPX_SHIFT

#define DSI1_HS_DLT5
#define DSI_HS_DLT5_INIT_MASK
#define DSI_HS_DLT5_INIT_SHIFT

#define DSI1_HS_DLT6
#define DSI_HS_DLT6_TA_GET_MASK
#define DSI_HS_DLT6_TA_GET_SHIFT
#define DSI_HS_DLT6_TA_SURE_MASK
#define DSI_HS_DLT6_TA_SURE_SHIFT
#define DSI_HS_DLT6_TA_GO_MASK
#define DSI_HS_DLT6_TA_GO_SHIFT
#define DSI_HS_DLT6_LP_LPX_MASK
#define DSI_HS_DLT6_LP_LPX_SHIFT

#define DSI1_HS_DLT7
#define DSI_HS_DLT7_LP_WUP_MASK
#define DSI_HS_DLT7_LP_WUP_SHIFT

#define DSI1_PHY_AFEC0

#define DSI1_PHY_AFEC1
#define DSI1_PHY_AFEC1_ACTRL_DLANE3_MASK
#define DSI1_PHY_AFEC1_ACTRL_DLANE3_SHIFT
#define DSI1_PHY_AFEC1_ACTRL_DLANE2_MASK
#define DSI1_PHY_AFEC1_ACTRL_DLANE2_SHIFT
#define DSI1_PHY_AFEC1_ACTRL_DLANE1_MASK
#define DSI1_PHY_AFEC1_ACTRL_DLANE1_SHIFT
#define DSI1_PHY_AFEC1_ACTRL_DLANE0_MASK
#define DSI1_PHY_AFEC1_ACTRL_DLANE0_SHIFT
#define DSI1_PHY_AFEC1_ACTRL_CLANE_MASK
#define DSI1_PHY_AFEC1_ACTRL_CLANE_SHIFT

#define DSI1_TST_SEL
#define DSI1_TST_MON
#define DSI1_PHY_TST1
#define DSI1_PHY_TST2
#define DSI1_PHY_FIFO_STAT
/* Actually, all registers in the range that aren't otherwise claimed
 * will return the ID.
 */
#define DSI1_ID

struct vc4_dsi_variant {};

/* General DSI hardware state. */
struct vc4_dsi {};

#define host_to_dsi(host)

#define to_vc4_dsi(_encoder)

#define bridge_to_vc4_dsi(_bridge)

static inline void
dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
{}

#define DSI_READ(offset)

#define DSI_WRITE(offset, val)
#define DSI_PORT_READ(offset)
#define DSI_PORT_WRITE(offset, val)
#define DSI_PORT_BIT(bit)

static const struct debugfs_reg32 dsi0_regs[] =;

static const struct debugfs_reg32 dsi1_regs[] =;

static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch)
{}

/* Enters or exits Ultra Low Power State. */
static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps)
{}

static u32
dsi_hs_timing(u32 ui_ns, u32 ns, u32 ui)
{}

/* ESC always runs at 100Mhz. */
#define ESC_TIME_NS

static u32
dsi_esc_timing(u32 ns)
{}

static void vc4_dsi_bridge_disable(struct drm_bridge *bridge,
				   struct drm_bridge_state *state)
{}

static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge,
					struct drm_bridge_state *state)
{}

/* Extends the mode's blank intervals to handle BCM2835's integer-only
 * DSI PLL divider.
 *
 * On 2835, PLLD is set to 2Ghz, and may not be changed by the display
 * driver since most peripherals are hanging off of the PLLD_PER
 * divider.  PLLD_DSI1, which drives our DSI bit clock (and therefore
 * the pixel clock), only has an integer divider off of DSI.
 *
 * To get our panel mode to refresh at the expected 60Hz, we need to
 * extend the horizontal blank time.  This means we drive a
 * higher-than-expected clock rate to the panel, but that's what the
 * firmware does too.
 */
static bool vc4_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
				      const struct drm_display_mode *mode,
				      struct drm_display_mode *adjusted_mode)
{}

static void vc4_dsi_bridge_pre_enable(struct drm_bridge *bridge,
				      struct drm_bridge_state *old_state)
{}

static void vc4_dsi_bridge_enable(struct drm_bridge *bridge,
				  struct drm_bridge_state *old_state)
{}

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

static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
				     const struct mipi_dsi_msg *msg)
{}

static const struct component_ops vc4_dsi_ops;
static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
			       struct mipi_dsi_device *device)
{}

static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
			       struct mipi_dsi_device *device)
{}

static const struct mipi_dsi_host_ops vc4_dsi_host_ops =;

static const struct drm_bridge_funcs vc4_dsi_bridge_funcs =;

static int vc4_dsi_late_register(struct drm_encoder *encoder)
{}

static const struct drm_encoder_funcs vc4_dsi_encoder_funcs =;

static const struct vc4_dsi_variant bcm2711_dsi1_variant =;

static const struct vc4_dsi_variant bcm2835_dsi0_variant =;

static const struct vc4_dsi_variant bcm2835_dsi1_variant =;

static const struct of_device_id vc4_dsi_dt_match[] =;

static void dsi_handle_error(struct vc4_dsi *dsi,
			     irqreturn_t *ret, u32 stat, u32 bit,
			     const char *type)
{}

/*
 * Initial handler for port 1 where we need the reg_dma workaround.
 * The register DMA writes sleep, so we can't do it in the top half.
 * Instead we use IRQF_ONESHOT so that the IRQ gets disabled in the
 * parent interrupt contrller until our interrupt thread is done.
 */
static irqreturn_t vc4_dsi_irq_defer_to_thread_handler(int irq, void *data)
{}

/*
 * Normal IRQ handler for port 0, or the threaded IRQ handler for port
 * 1 where we need the reg_dma workaround.
 */
static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
{}

/**
 * vc4_dsi_init_phy_clocks - Exposes clocks generated by the analog
 * PHY that are consumed by CPRMAN (clk-bcm2835.c).
 * @dsi: DSI encoder
 */
static int
vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi)
{}

static void vc4_dsi_dma_mem_release(void *ptr)
{}

static void vc4_dsi_dma_chan_release(void *ptr)
{}

static void vc4_dsi_release(struct kref *kref)
{}

static void vc4_dsi_get(struct vc4_dsi *dsi)
{}

static void vc4_dsi_put(struct vc4_dsi *dsi)
{}

static void vc4_dsi_release_action(struct drm_device *drm, void *ptr)
{}

static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
{}

static const struct component_ops vc4_dsi_ops =;

static int vc4_dsi_dev_probe(struct platform_device *pdev)
{}

static void vc4_dsi_dev_remove(struct platform_device *pdev)
{}

struct platform_driver vc4_dsi_driver =;