#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_modes.h>
#include <drm/drm_of.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/phy/phy.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include "zynqmp_disp.h"
#include "zynqmp_dp.h"
#include "zynqmp_dpsub.h"
#include "zynqmp_kms.h"
static uint zynqmp_dp_aux_timeout_ms = …;
module_param_named(aux_timeout_ms, zynqmp_dp_aux_timeout_ms, uint, 0444);
MODULE_PARM_DESC(…) …;
static uint zynqmp_dp_power_on_delay_ms = …;
module_param_named(power_on_delay_ms, zynqmp_dp_power_on_delay_ms, uint, 0444);
MODULE_PARM_DESC(…) …;
#define ZYNQMP_DP_LINK_BW_SET …
#define ZYNQMP_DP_LANE_COUNT_SET …
#define ZYNQMP_DP_ENHANCED_FRAME_EN …
#define ZYNQMP_DP_TRAINING_PATTERN_SET …
#define ZYNQMP_DP_SCRAMBLING_DISABLE …
#define ZYNQMP_DP_DOWNSPREAD_CTL …
#define ZYNQMP_DP_SOFTWARE_RESET …
#define ZYNQMP_DP_SOFTWARE_RESET_STREAM1 …
#define ZYNQMP_DP_SOFTWARE_RESET_STREAM2 …
#define ZYNQMP_DP_SOFTWARE_RESET_STREAM3 …
#define ZYNQMP_DP_SOFTWARE_RESET_STREAM4 …
#define ZYNQMP_DP_SOFTWARE_RESET_AUX …
#define ZYNQMP_DP_SOFTWARE_RESET_ALL …
#define ZYNQMP_DP_TRANSMITTER_ENABLE …
#define ZYNQMP_DP_MAIN_STREAM_ENABLE …
#define ZYNQMP_DP_FORCE_SCRAMBLER_RESET …
#define ZYNQMP_DP_VERSION …
#define ZYNQMP_DP_VERSION_MAJOR_MASK …
#define ZYNQMP_DP_VERSION_MAJOR_SHIFT …
#define ZYNQMP_DP_VERSION_MINOR_MASK …
#define ZYNQMP_DP_VERSION_MINOR_SHIFT …
#define ZYNQMP_DP_VERSION_REVISION_MASK …
#define ZYNQMP_DP_VERSION_REVISION_SHIFT …
#define ZYNQMP_DP_VERSION_PATCH_MASK …
#define ZYNQMP_DP_VERSION_PATCH_SHIFT …
#define ZYNQMP_DP_VERSION_INTERNAL_MASK …
#define ZYNQMP_DP_VERSION_INTERNAL_SHIFT …
#define ZYNQMP_DP_CORE_ID …
#define ZYNQMP_DP_CORE_ID_MAJOR_MASK …
#define ZYNQMP_DP_CORE_ID_MAJOR_SHIFT …
#define ZYNQMP_DP_CORE_ID_MINOR_MASK …
#define ZYNQMP_DP_CORE_ID_MINOR_SHIFT …
#define ZYNQMP_DP_CORE_ID_REVISION_MASK …
#define ZYNQMP_DP_CORE_ID_REVISION_SHIFT …
#define ZYNQMP_DP_CORE_ID_DIRECTION …
#define ZYNQMP_DP_AUX_COMMAND …
#define ZYNQMP_DP_AUX_COMMAND_CMD_SHIFT …
#define ZYNQMP_DP_AUX_COMMAND_ADDRESS_ONLY …
#define ZYNQMP_DP_AUX_COMMAND_BYTES_SHIFT …
#define ZYNQMP_DP_AUX_WRITE_FIFO …
#define ZYNQMP_DP_AUX_ADDRESS …
#define ZYNQMP_DP_AUX_CLK_DIVIDER …
#define ZYNQMP_DP_AUX_CLK_DIVIDER_AUX_FILTER_SHIFT …
#define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE …
#define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_HPD …
#define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REQUEST …
#define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY …
#define ZYNQMP_DP_INTERRUPT_SIGNAL_STATE_REPLY_TIMEOUT …
#define ZYNQMP_DP_AUX_REPLY_DATA …
#define ZYNQMP_DP_AUX_REPLY_CODE …
#define ZYNQMP_DP_AUX_REPLY_CODE_AUX_ACK …
#define ZYNQMP_DP_AUX_REPLY_CODE_AUX_NACK …
#define ZYNQMP_DP_AUX_REPLY_CODE_AUX_DEFER …
#define ZYNQMP_DP_AUX_REPLY_CODE_I2C_ACK …
#define ZYNQMP_DP_AUX_REPLY_CODE_I2C_NACK …
#define ZYNQMP_DP_AUX_REPLY_CODE_I2C_DEFER …
#define ZYNQMP_DP_AUX_REPLY_COUNT …
#define ZYNQMP_DP_REPLY_DATA_COUNT …
#define ZYNQMP_DP_REPLY_DATA_COUNT_MASK …
#define ZYNQMP_DP_INT_STATUS …
#define ZYNQMP_DP_INT_MASK …
#define ZYNQMP_DP_INT_EN …
#define ZYNQMP_DP_INT_DS …
#define ZYNQMP_DP_INT_HPD_IRQ …
#define ZYNQMP_DP_INT_HPD_EVENT …
#define ZYNQMP_DP_INT_REPLY_RECEIVED …
#define ZYNQMP_DP_INT_REPLY_TIMEOUT …
#define ZYNQMP_DP_INT_HPD_PULSE_DET …
#define ZYNQMP_DP_INT_EXT_PKT_TXD …
#define ZYNQMP_DP_INT_LIV_ABUF_UNDRFLW …
#define ZYNQMP_DP_INT_VBLANK_START …
#define ZYNQMP_DP_INT_PIXEL1_MATCH …
#define ZYNQMP_DP_INT_PIXEL0_MATCH …
#define ZYNQMP_DP_INT_CHBUF_UNDERFLW_MASK …
#define ZYNQMP_DP_INT_CHBUF_OVERFLW_MASK …
#define ZYNQMP_DP_INT_CUST_TS_2 …
#define ZYNQMP_DP_INT_CUST_TS …
#define ZYNQMP_DP_INT_EXT_VSYNC_TS …
#define ZYNQMP_DP_INT_VSYNC_TS …
#define ZYNQMP_DP_INT_ALL …
#define ZYNQMP_DP_MAIN_STREAM_HTOTAL …
#define ZYNQMP_DP_MAIN_STREAM_VTOTAL …
#define ZYNQMP_DP_MAIN_STREAM_POLARITY …
#define ZYNQMP_DP_MAIN_STREAM_POLARITY_HSYNC_SHIFT …
#define ZYNQMP_DP_MAIN_STREAM_POLARITY_VSYNC_SHIFT …
#define ZYNQMP_DP_MAIN_STREAM_HSWIDTH …
#define ZYNQMP_DP_MAIN_STREAM_VSWIDTH …
#define ZYNQMP_DP_MAIN_STREAM_HRES …
#define ZYNQMP_DP_MAIN_STREAM_VRES …
#define ZYNQMP_DP_MAIN_STREAM_HSTART …
#define ZYNQMP_DP_MAIN_STREAM_VSTART …
#define ZYNQMP_DP_MAIN_STREAM_MISC0 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_SYNC_LOCK …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_RGB …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_422 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_YCRCB_444 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_COMP_FORMAT_MASK …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_DYNAMIC_RANGE …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_YCBCR_COLR …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_6 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_8 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_10 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_12 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_16 …
#define ZYNQMP_DP_MAIN_STREAM_MISC0_BPC_MASK …
#define ZYNQMP_DP_MAIN_STREAM_MISC1 …
#define ZYNQMP_DP_MAIN_STREAM_MISC1_Y_ONLY_EN …
#define ZYNQMP_DP_MAIN_STREAM_M_VID …
#define ZYNQMP_DP_MSA_TRANSFER_UNIT_SIZE …
#define ZYNQMP_DP_MSA_TRANSFER_UNIT_SIZE_TU_SIZE_DEF …
#define ZYNQMP_DP_MAIN_STREAM_N_VID …
#define ZYNQMP_DP_USER_PIX_WIDTH …
#define ZYNQMP_DP_USER_DATA_COUNT_PER_LANE …
#define ZYNQMP_DP_MIN_BYTES_PER_TU …
#define ZYNQMP_DP_FRAC_BYTES_PER_TU …
#define ZYNQMP_DP_INIT_WAIT …
#define ZYNQMP_DP_PHY_RESET …
#define ZYNQMP_DP_PHY_RESET_PHY_RESET …
#define ZYNQMP_DP_PHY_RESET_GTTX_RESET …
#define ZYNQMP_DP_PHY_RESET_PHY_PMA_RESET …
#define ZYNQMP_DP_PHY_RESET_PHY_PCS_RESET …
#define ZYNQMP_DP_PHY_RESET_ALL_RESET …
#define ZYNQMP_DP_PHY_PREEMPHASIS_LANE_0 …
#define ZYNQMP_DP_PHY_PREEMPHASIS_LANE_1 …
#define ZYNQMP_DP_PHY_PREEMPHASIS_LANE_2 …
#define ZYNQMP_DP_PHY_PREEMPHASIS_LANE_3 …
#define ZYNQMP_DP_PHY_VOLTAGE_DIFF_LANE_0 …
#define ZYNQMP_DP_PHY_VOLTAGE_DIFF_LANE_1 …
#define ZYNQMP_DP_PHY_VOLTAGE_DIFF_LANE_2 …
#define ZYNQMP_DP_PHY_VOLTAGE_DIFF_LANE_3 …
#define ZYNQMP_DP_PHY_CLOCK_SELECT …
#define ZYNQMP_DP_PHY_CLOCK_SELECT_1_62G …
#define ZYNQMP_DP_PHY_CLOCK_SELECT_2_70G …
#define ZYNQMP_DP_PHY_CLOCK_SELECT_5_40G …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_0 …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_1 …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_2 …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN_LANE_3 …
#define ZYNQMP_DP_TX_PHY_POWER_DOWN_ALL …
#define ZYNQMP_DP_PHY_PRECURSOR_LANE_0 …
#define ZYNQMP_DP_PHY_PRECURSOR_LANE_1 …
#define ZYNQMP_DP_PHY_PRECURSOR_LANE_2 …
#define ZYNQMP_DP_PHY_PRECURSOR_LANE_3 …
#define ZYNQMP_DP_PHY_POSTCURSOR_LANE_0 …
#define ZYNQMP_DP_PHY_POSTCURSOR_LANE_1 …
#define ZYNQMP_DP_PHY_POSTCURSOR_LANE_2 …
#define ZYNQMP_DP_PHY_POSTCURSOR_LANE_3 …
#define ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_0 …
#define ZYNQMP_DP_SUB_TX_PHY_PRECURSOR_LANE_1 …
#define ZYNQMP_DP_PHY_STATUS …
#define ZYNQMP_DP_PHY_STATUS_PLL_LOCKED_SHIFT …
#define ZYNQMP_DP_PHY_STATUS_FPGA_PLL_LOCKED …
#define ZYNQMP_DP_TX_AUDIO_CONTROL …
#define ZYNQMP_DP_TX_AUDIO_CHANNELS …
#define ZYNQMP_DP_TX_AUDIO_INFO_DATA …
#define ZYNQMP_DP_TX_M_AUD …
#define ZYNQMP_DP_TX_N_AUD …
#define ZYNQMP_DP_TX_AUDIO_EXT_DATA …
#define ZYNQMP_DP_MAX_LANES …
#define ZYNQMP_MAX_FREQ …
#define DP_REDUCED_BIT_RATE …
#define DP_HIGH_BIT_RATE …
#define DP_HIGH_BIT_RATE2 …
#define DP_MAX_TRAINING_TRIES …
#define DP_V1_2 …
struct zynqmp_dp_link_config { … };
struct zynqmp_dp_mode { … };
struct zynqmp_dp_config { … };
struct zynqmp_dp { … };
static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge)
{ … }
static void zynqmp_dp_write(struct zynqmp_dp *dp, int offset, u32 val)
{ … }
static u32 zynqmp_dp_read(struct zynqmp_dp *dp, int offset)
{ … }
static void zynqmp_dp_clr(struct zynqmp_dp *dp, int offset, u32 clr)
{ … }
static void zynqmp_dp_set(struct zynqmp_dp *dp, int offset, u32 set)
{ … }
#define RST_TIMEOUT_MS …
static int zynqmp_dp_reset(struct zynqmp_dp *dp, bool assert)
{ … }
static int zynqmp_dp_phy_init(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_phy_exit(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_phy_probe(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_phy_ready(struct zynqmp_dp *dp)
{ … }
static inline int zynqmp_dp_max_rate(int link_rate, u8 lane_num, u8 bpp)
{ … }
static int zynqmp_dp_mode_configure(struct zynqmp_dp *dp, int pclock,
u8 current_bw)
{ … }
static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp,
u8 link_status[DP_LINK_STATUS_SIZE])
{ … }
static int zynqmp_dp_update_vs_emph(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_link_train_cr(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_link_train_ce(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_train(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_train_loop(struct zynqmp_dp *dp)
{ … }
#define AUX_READ_BIT …
static int zynqmp_dp_aux_cmd_submit(struct zynqmp_dp *dp, u32 cmd, u16 addr,
u8 *buf, u8 bytes, u8 *reply)
{ … }
static ssize_t
zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{ … }
static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_update_misc(struct zynqmp_dp *dp)
{ … }
static int zynqmp_dp_set_format(struct zynqmp_dp *dp,
const struct drm_display_info *info,
enum zynqmp_dpsub_format format,
unsigned int bpc)
{ … }
static void
zynqmp_dp_encoder_mode_set_transfer_unit(struct zynqmp_dp *dp,
const struct drm_display_mode *mode)
{ … }
static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
const struct drm_display_mode *mode)
{ … }
static struct zynqmp_disp_layer *
zynqmp_dp_disp_connected_live_layer(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
struct drm_bridge_state *old_bridge_state)
{ … }
static void zynqmp_dp_disp_disable(struct zynqmp_dp *dp,
struct drm_bridge_state *old_bridge_state)
{ … }
static int zynqmp_dp_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{ … }
static void zynqmp_dp_bridge_detach(struct drm_bridge *bridge)
{ … }
static enum drm_mode_status
zynqmp_dp_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode)
{ … }
static void zynqmp_dp_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ … }
static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ … }
#define ZYNQMP_DP_MIN_H_BACKPORCH …
static int zynqmp_dp_bridge_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_connector_status zynqmp_dp_bridge_detect(struct drm_bridge *bridge)
{ … }
static const struct drm_edid *zynqmp_dp_bridge_edid_read(struct drm_bridge *bridge,
struct drm_connector *connector)
{ … }
static u32 *zynqmp_dp_bridge_default_bus_fmts(unsigned int *num_input_fmts)
{ … }
static u32 *
zynqmp_dp_bridge_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 const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = …;
void zynqmp_dp_enable_vblank(struct zynqmp_dp *dp)
{ … }
void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp)
{ … }
static void zynqmp_dp_hpd_work_func(struct work_struct *work)
{ … }
static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
{ … }
int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
{ … }
void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub)
{ … }