Commit c943b494 authored by Chandan Uddaraju's avatar Chandan Uddaraju Committed by Rob Clark

drm/msm/dp: add displayPort driver support

Add the needed displayPort files to enable DP driver
on msm target.

"dp_display" module is the main module that calls into
other sub-modules. "dp_drm" file represents the interface
between DRM framework and DP driver.

Changes in v12:

-- Add support of pm ops in display port driver
-- Clear bpp depth bits before writing to MISC register
-- Fix edid read

Previous Change log:
https://lkml.kernel.org/lkml/20200818051137.21478-3-tanmay@codeaurora.org/Signed-off-by: default avatarChandan Uddaraju <chandanu@codeaurora.org>
Signed-off-by: default avatarVara Reddy <varar@codeaurora.org>
Signed-off-by: default avatarTanmay Shah <tanmay@codeaurora.org>
Co-developed-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
Co-developed-by: default avatarKuogee Hsieh <khsieh@codeaurora.org>
Signed-off-by: default avatarKuogee Hsieh <khsieh@codeaurora.org>
Co-developed-by: default avatarGuenter Roeck <groeck@chromium.org>
Signed-off-by: default avatarGuenter Roeck <groeck@chromium.org>
Co-developed-by: default avatarStephen Boyd <swboyd@chromium.org>
Signed-off-by: default avatarStephen Boyd <swboyd@chromium.org>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent b22960b8
......@@ -58,6 +58,14 @@ config DRM_MSM_HDMI_HDCP
help
Choose this option to enable HDCP state machine
config DRM_MSM_DP
bool "Enable DisplayPort support in MSM DRM driver"
depends on DRM_MSM
help
Compile in support for DP driver in MSM DRM driver. DP external
display support is enabled through this config option. It can
be primary or secondary display on device.
config DRM_MSM_DSI
bool "Enable DSI support in MSM DRM driver"
depends on DRM_MSM
......
......@@ -2,6 +2,7 @@
ccflags-y := -I $(srctree)/$(src)
ccflags-y += -I $(srctree)/$(src)/disp/dpu1
ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
msm-y := \
adreno/adreno_device.o \
......@@ -99,6 +100,17 @@ msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o
msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o
msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_catalog.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
dp/dp_parser.o \
dp/dp_power.o
msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o
msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o
......
......@@ -1001,6 +1001,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc,
trace_dpu_enc_mode_set(DRMID(drm_enc));
if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp)
msm_dp_display_mode_set(priv->dp, drm_enc, mode, adj_mode);
list_for_each_entry(conn_iter, connector_list, head)
if (conn_iter->encoder == drm_enc)
conn = conn_iter;
......@@ -1146,6 +1149,7 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
int ret = 0;
struct msm_drm_private *priv;
struct drm_display_mode *cur_mode = NULL;
if (!drm_enc) {
......@@ -1156,6 +1160,7 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
mutex_lock(&dpu_enc->enc_lock);
cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
priv = drm_enc->dev->dev_private;
trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay,
cur_mode->vdisplay);
......@@ -1176,6 +1181,15 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
_dpu_encoder_virt_enable_helper(drm_enc);
if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
ret = msm_dp_display_enable(priv->dp,
drm_enc);
if (ret) {
DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n",
ret);
goto out;
}
}
dpu_enc->enabled = true;
out:
......@@ -1234,6 +1248,11 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
if (msm_dp_display_disable(priv->dp, drm_enc))
DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n");
}
mutex_unlock(&dpu_enc->enc_lock);
}
......
......@@ -100,6 +100,14 @@ static void drm_mode_to_intf_timing_params(
* display_v_end -= mode->hsync_start - mode->hdisplay;
* }
*/
/* for DP/EDP, Shift timings to align it to bottom right */
if ((phys_enc->hw_intf->cap->type == INTF_DP) ||
(phys_enc->hw_intf->cap->type == INTF_EDP)) {
timing->h_back_porch += timing->h_front_porch;
timing->h_front_porch = 0;
timing->v_back_porch += timing->v_front_porch;
timing->v_front_porch = 0;
}
}
static u32 get_horizontal_total(const struct intf_timing_params *timing)
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_AUX_H_
#define _DP_AUX_H_
#include "dp_catalog.h"
#include <drm/drm_dp_helper.h>
#define DP_AUX_ERR_NONE 0
#define DP_AUX_ERR_ADDR -1
#define DP_AUX_ERR_TOUT -2
#define DP_AUX_ERR_NACK -3
#define DP_AUX_ERR_DEFER -4
#define DP_AUX_ERR_NACK_DEFER -5
#define DP_AUX_ERR_PHY -6
int dp_aux_register(struct drm_dp_aux *dp_aux);
void dp_aux_unregister(struct drm_dp_aux *dp_aux);
void dp_aux_isr(struct drm_dp_aux *dp_aux);
void dp_aux_init(struct drm_dp_aux *dp_aux);
void dp_aux_deinit(struct drm_dp_aux *dp_aux);
void dp_aux_reconfig(struct drm_dp_aux *dp_aux);
struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog);
void dp_aux_put(struct drm_dp_aux *aux);
#endif /*__DP_AUX_H_*/
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_CATALOG_H_
#define _DP_CATALOG_H_
#include "dp_parser.h"
/* interrupts */
#define DP_INTR_HPD BIT(0)
#define DP_INTR_AUX_I2C_DONE BIT(3)
#define DP_INTR_WRONG_ADDR BIT(6)
#define DP_INTR_TIMEOUT BIT(9)
#define DP_INTR_NACK_DEFER BIT(12)
#define DP_INTR_WRONG_DATA_CNT BIT(15)
#define DP_INTR_I2C_NACK BIT(18)
#define DP_INTR_I2C_DEFER BIT(21)
#define DP_INTR_PLL_UNLOCKED BIT(24)
#define DP_INTR_AUX_ERROR BIT(27)
#define DP_INTR_READY_FOR_VIDEO BIT(0)
#define DP_INTR_IDLE_PATTERN_SENT BIT(3)
#define DP_INTR_FRAME_END BIT(6)
#define DP_INTR_CRC_UPDATED BIT(9)
#define DP_AUX_CFG_MAX_VALUE_CNT 3
/* PHY AUX config registers */
enum dp_phy_aux_config_type {
PHY_AUX_CFG0,
PHY_AUX_CFG1,
PHY_AUX_CFG2,
PHY_AUX_CFG3,
PHY_AUX_CFG4,
PHY_AUX_CFG5,
PHY_AUX_CFG6,
PHY_AUX_CFG7,
PHY_AUX_CFG8,
PHY_AUX_CFG9,
PHY_AUX_CFG_MAX,
};
struct dp_catalog {
u32 aux_data;
u32 total;
u32 sync_start;
u32 width_blanking;
u32 dp_active;
};
/* AUX APIs */
u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog);
int dp_catalog_aux_write_data(struct dp_catalog *dp_catalog);
int dp_catalog_aux_write_trans(struct dp_catalog *dp_catalog);
int dp_catalog_aux_clear_trans(struct dp_catalog *dp_catalog, bool read);
int dp_catalog_aux_clear_hw_interrupts(struct dp_catalog *dp_catalog);
void dp_catalog_aux_reset(struct dp_catalog *dp_catalog);
void dp_catalog_aux_enable(struct dp_catalog *dp_catalog, bool enable);
void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog,
enum dp_phy_aux_config_type type);
void dp_catalog_aux_setup(struct dp_catalog *dp_catalog);
int dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog);
/* DP Controller APIs */
void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state);
void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 config);
void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool enable);
void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb);
void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
u32 stream_rate_khz, bool fixed_nvid);
int dp_catalog_ctrl_set_pattern(struct dp_catalog *dp_catalog, u32 pattern);
void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_usb_reset(struct dp_catalog *dp_catalog, bool flip);
bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog, bool enable);
void dp_catalog_ctrl_phy_reset(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_phy_lane_cfg(struct dp_catalog *dp_catalog, bool flipped,
u8 lane_cnt);
int dp_catalog_ctrl_update_vx_px(struct dp_catalog *dp_catalog, u8 v_level,
u8 p_level);
int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_update_transfer_unit(struct dp_catalog *dp_catalog,
u32 dp_tu, u32 valid_boundary,
u32 valid_boundary2);
void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog,
u32 pattern);
u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog);
/* DP Panel APIs */
int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog);
void dp_catalog_dump_regs(struct dp_catalog *dp_catalog);
void dp_catalog_panel_tpg_enable(struct dp_catalog *dp_catalog,
struct drm_display_mode *drm_mode);
void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog);
struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io);
#endif /* _DP_CATALOG_H_ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_CTRL_H_
#define _DP_CTRL_H_
#include "dp_aux.h"
#include "dp_panel.h"
#include "dp_link.h"
#include "dp_parser.h"
#include "dp_power.h"
#include "dp_catalog.h"
struct dp_ctrl {
bool orientation;
atomic_t aborted;
u32 pixel_rate;
};
int dp_ctrl_host_init(struct dp_ctrl *dp_ctrl, bool flip);
void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl);
int dp_ctrl_on(struct dp_ctrl *dp_ctrl);
int dp_ctrl_off(struct dp_ctrl *dp_ctrl);
void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl);
void dp_ctrl_isr(struct dp_ctrl *dp_ctrl);
void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl);
struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
struct dp_panel *panel, struct drm_dp_aux *aux,
struct dp_power *power, struct dp_catalog *catalog,
struct dp_parser *parser);
void dp_ctrl_put(struct dp_ctrl *dp_ctrl);
#endif /* _DP_CTRL_H_ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_DISPLAY_H_
#define _DP_DISPLAY_H_
#include "dp_panel.h"
struct msm_dp {
struct drm_device *drm_dev;
struct drm_connector *connector;
struct drm_encoder *encoder;
bool is_connected;
struct mutex connect_mutex;
u32 max_pclk_khz;
u32 max_dp_lanes;
};
int dp_display_validate_mode(struct msm_dp *dp_display, u32 mode_pclk_khz);
int dp_display_get_modes(struct msm_dp *dp_display,
struct dp_display_mode *dp_mode);
int dp_display_request_irq(struct msm_dp *dp_display);
bool dp_display_check_video_test(struct msm_dp *dp_display);
int dp_display_get_test_bpp(struct msm_dp *dp_display);
#endif /* _DP_DISPLAY_H_ */
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h>
#include "msm_drv.h"
#include "msm_kms.h"
#include "dp_drm.h"
struct dp_connector {
struct drm_connector base;
struct msm_dp *dp_display;
};
#define to_dp_connector(x) container_of(x, struct dp_connector, base)
/**
* dp_connector_detect - callback to determine if connector is connected
* @conn: Pointer to drm connector structure
* @force: Force detect setting from drm framework
* Returns: Connector 'is connected' status
*/
static enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
bool force)
{
struct msm_dp *dp;
dp = to_dp_connector(conn)->dp_display;
DRM_DEBUG_DP("is_connected = %s\n",
(dp->is_connected) ? "true" : "false");
return (dp->is_connected) ? connector_status_connected :
connector_status_disconnected;
}
/**
* dp_connector_get_modes - callback to add drm modes via drm_mode_probed_add()
* @connector: Pointer to drm connector structure
* Returns: Number of modes added
*/
static int dp_connector_get_modes(struct drm_connector *connector)
{
int rc = 0;
struct msm_dp *dp;
struct dp_display_mode *dp_mode = NULL;
struct drm_display_mode *m, drm_mode;
if (!connector)
return 0;
dp = to_dp_connector(connector)->dp_display;
dp_mode = kzalloc(sizeof(*dp_mode), GFP_KERNEL);
if (!dp_mode)
return 0;
mutex_lock(&dp->connect_mutex);
/* pluggable case assumes EDID is read when HPD */
if (dp->is_connected) {
/*
*The get_modes() function might return one mode that is stored
* in dp_mode when compliance test is in progress. If not, the
* return value is equal to the total number of modes supported
* by the sink
*/
rc = dp_display_get_modes(dp, dp_mode);
if (rc <= 0) {
DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
kfree(dp_mode);
mutex_unlock(&dp->connect_mutex);
return rc;
}
if (dp_mode->drm_mode.clock) { /* valid DP mode */
memset(&drm_mode, 0x0, sizeof(drm_mode));
drm_mode_copy(&drm_mode, &dp_mode->drm_mode);
m = drm_mode_duplicate(connector->dev, &drm_mode);
if (!m) {
DRM_ERROR("failed to add mode %ux%u\n",
drm_mode.hdisplay,
drm_mode.vdisplay);
kfree(dp_mode);
mutex_unlock(&dp->connect_mutex);
return 0;
}
drm_mode_probed_add(connector, m);
}
} else {
DRM_DEBUG_DP("No sink connected\n");
}
mutex_unlock(&dp->connect_mutex);
kfree(dp_mode);
return rc;
}
/**
* dp_connector_mode_valid - callback to determine if specified mode is valid
* @connector: Pointer to drm connector structure
* @mode: Pointer to drm mode structure
* Returns: Validity status for specified mode
*/
static enum drm_mode_status dp_connector_mode_valid(
struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct msm_dp *dp_disp;
dp_disp = to_dp_connector(connector)->dp_display;
if ((dp_disp->max_pclk_khz <= 0) ||
(dp_disp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) ||
(mode->clock > dp_disp->max_pclk_khz))
return MODE_BAD;
return dp_display_validate_mode(dp_disp, mode->clock);
}
static const struct drm_connector_funcs dp_connector_funcs = {
.detect = dp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs dp_connector_helper_funcs = {
.get_modes = dp_connector_get_modes,
.mode_valid = dp_connector_mode_valid,
};
/* connector initialization */
struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display)
{
struct drm_connector *connector = NULL;
struct dp_connector *dp_connector;
int ret;
dp_connector = devm_kzalloc(dp_display->drm_dev->dev,
sizeof(*dp_connector),
GFP_KERNEL);
if (!dp_connector)
return ERR_PTR(-ENOMEM);
dp_connector->dp_display = dp_display;
connector = &dp_connector->base;
ret = drm_connector_init(dp_display->drm_dev, connector,
&dp_connector_funcs,
DRM_MODE_CONNECTOR_DisplayPort);
if (ret)
return ERR_PTR(ret);
drm_connector_helper_add(connector, &dp_connector_helper_funcs);
/*
* Enable HPD to let hpd event is handled when cable is connected.
*/
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_attach_encoder(connector, dp_display->encoder);
return connector;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_DRM_H_
#define _DP_DRM_H_
#include <linux/types.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include "msm_drv.h"
#include "dp_display.h"
struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display);
#endif /* _DP_DRM_H_ */
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
#include <linux/slab.h>
#include <linux/device.h>
#include "dp_hpd.h"
/* DP specific VDM commands */
#define DP_USBPD_VDM_STATUS 0x10
#define DP_USBPD_VDM_CONFIGURE 0x11
/* USBPD-TypeC specific Macros */
#define VDM_VERSION 0x0
#define USB_C_DP_SID 0xFF01
struct dp_hpd_private {
struct device *dev;
struct dp_usbpd_cb *dp_cb;
struct dp_usbpd dp_usbpd;
};
static int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd)
{
int rc = 0;
struct dp_hpd_private *hpd_priv;
hpd_priv = container_of(dp_usbpd, struct dp_hpd_private,
dp_usbpd);
dp_usbpd->hpd_high = hpd;
if (!hpd_priv->dp_cb && !hpd_priv->dp_cb->configure
&& !hpd_priv->dp_cb->disconnect) {
pr_err("hpd dp_cb not initialized\n");
return -EINVAL;
}
if (hpd)
hpd_priv->dp_cb->configure(hpd_priv->dev);
else
hpd_priv->dp_cb->disconnect(hpd_priv->dev);
return rc;
}
struct dp_usbpd *dp_hpd_get(struct device *dev, struct dp_usbpd_cb *cb)
{
struct dp_hpd_private *dp_hpd;
if (!cb) {
pr_err("invalid cb data\n");
return ERR_PTR(-EINVAL);
}
dp_hpd = devm_kzalloc(dev, sizeof(*dp_hpd), GFP_KERNEL);
if (!dp_hpd)
return ERR_PTR(-ENOMEM);
dp_hpd->dev = dev;
dp_hpd->dp_cb = cb;
dp_hpd->dp_usbpd.connect = dp_hpd_connect;
return &dp_hpd->dp_usbpd;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_HPD_H_
#define _DP_HPD_H_
//#include <linux/usb/usbpd.h>
#include <linux/types.h>
#include <linux/device.h>
enum plug_orientation {
ORIENTATION_NONE,
ORIENTATION_CC1,
ORIENTATION_CC2,
};
/**
* struct dp_usbpd - DisplayPort status
*
* @orientation: plug orientation configuration
* @low_pow_st: low power state
* @adaptor_dp_en: adaptor functionality enabled
* @multi_func: multi-function preferred
* @usb_config_req: request to switch to usb
* @exit_dp_mode: request exit from displayport mode
* @hpd_high: Hot Plug Detect signal is high.
* @hpd_irq: Change in the status since last message
* @alt_mode_cfg_done: bool to specify alt mode status
* @debug_en: bool to specify debug mode
* @connect: simulate disconnect or connect for debug mode
*/
struct dp_usbpd {
enum plug_orientation orientation;
bool low_pow_st;
bool adaptor_dp_en;
bool multi_func;
bool usb_config_req;
bool exit_dp_mode;
bool hpd_high;
bool hpd_irq;
bool alt_mode_cfg_done;
bool debug_en;
int (*connect)(struct dp_usbpd *dp_usbpd, bool hpd);
};
/**
* struct dp_usbpd_cb - callback functions provided by the client
*
* @configure: called by usbpd module when PD communication has
* been completed and the usb peripheral has been configured on
* dp mode.
* @disconnect: notify the cable disconnect issued by usb.
* @attention: notify any attention message issued by usb.
*/
struct dp_usbpd_cb {
int (*configure)(struct device *dev);
int (*disconnect)(struct device *dev);
int (*attention)(struct device *dev);
};
/**
* dp_hpd_get() - setup hpd module
*
* @dev: device instance of the caller
* @cb: struct containing callback function pointers.
*
* This function allows the client to initialize the usbpd
* module. The module will communicate with HPD module.
*/
struct dp_usbpd *dp_hpd_get(struct device *dev, struct dp_usbpd_cb *cb);
int dp_hpd_register(struct dp_usbpd *dp_usbpd);
void dp_hpd_unregister(struct dp_usbpd *dp_usbpd);
#endif /* _DP_HPD_H_ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _DP_LINK_H_
#define _DP_LINK_H_
#include "dp_aux.h"
#define DS_PORT_STATUS_CHANGED 0x200
#define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
#define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
struct dp_link_info {
unsigned char revision;
unsigned int rate;
unsigned int num_lanes;
unsigned long capabilities;
};
enum dp_link_voltage_level {
DP_TRAIN_VOLTAGE_SWING_LVL_0 = 0,
DP_TRAIN_VOLTAGE_SWING_LVL_1 = 1,
DP_TRAIN_VOLTAGE_SWING_LVL_2 = 2,
DP_TRAIN_VOLTAGE_SWING_MAX = DP_TRAIN_VOLTAGE_SWING_LVL_2,
};
enum dp_link_preemaphasis_level {
DP_TRAIN_PRE_EMPHASIS_LVL_0 = 0,
DP_TRAIN_PRE_EMPHASIS_LVL_1 = 1,
DP_TRAIN_PRE_EMPHASIS_LVL_2 = 2,
DP_TRAIN_PRE_EMPHASIS_MAX = DP_TRAIN_PRE_EMPHASIS_LVL_2,
};
struct dp_link_test_video {
u32 test_video_pattern;
u32 test_bit_depth;
u32 test_dyn_range;
u32 test_h_total;
u32 test_v_total;
u32 test_h_start;
u32 test_v_start;
u32 test_hsync_pol;
u32 test_hsync_width;
u32 test_vsync_pol;
u32 test_vsync_width;
u32 test_h_width;
u32 test_v_height;
u32 test_rr_d;
u32 test_rr_n;
};
struct dp_link_test_audio {
u32 test_audio_sampling_rate;
u32 test_audio_channel_count;
u32 test_audio_pattern_type;
u32 test_audio_period_ch_1;
u32 test_audio_period_ch_2;
u32 test_audio_period_ch_3;
u32 test_audio_period_ch_4;
u32 test_audio_period_ch_5;
u32 test_audio_period_ch_6;
u32 test_audio_period_ch_7;
u32 test_audio_period_ch_8;
};
struct dp_link_phy_params {
u32 phy_test_pattern_sel;
u8 v_level;
u8 p_level;
};
struct dp_link {
u32 sink_request;
u32 test_response;
bool psm_enabled;
u8 sink_count;
struct dp_link_test_video test_video;
struct dp_link_test_audio test_audio;
struct dp_link_phy_params phy_params;
struct dp_link_info link_params;
};
/**
* mdss_dp_test_bit_depth_to_bpp() - convert test bit depth to bpp
* @tbd: test bit depth
*
* Returns the bits per pixel (bpp) to be used corresponding to the
* git bit depth value. This function assumes that bit depth has
* already been validated.
*/
static inline u32 dp_link_bit_depth_to_bpp(u32 tbd)
{
/*
* Few simplistic rules and assumptions made here:
* 1. Bit depth is per color component
* 2. If bit depth is unknown return 0
* 3. Assume 3 color components
*/
switch (tbd) {
case DP_TEST_BIT_DEPTH_6:
return 18;
case DP_TEST_BIT_DEPTH_8:
return 24;
case DP_TEST_BIT_DEPTH_10:
return 30;
case DP_TEST_BIT_DEPTH_UNKNOWN:
default:
return 0;
}
}
u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp);
int dp_link_process_request(struct dp_link *dp_link);
int dp_link_get_colorimetry_config(struct dp_link *dp_link);
int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status);
bool dp_link_send_test_response(struct dp_link *dp_link);
int dp_link_psm_config(struct dp_link *dp_link,
struct dp_link_info *link_info, bool enable);
bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum);
/**
* dp_link_get() - get the functionalities of dp test module
*
*
* return: a pointer to dp_link struct
*/
struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux);
#endif /* _DP_LINK_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1352,6 +1352,7 @@ static int __init msm_drm_register(void)
msm_dsi_register();
msm_edp_register();
msm_hdmi_register();
msm_dp_register();
adreno_register();
return platform_driver_register(&msm_platform_driver);
}
......@@ -1360,6 +1361,7 @@ static void __exit msm_drm_unregister(void)
{
DBG("fini");
platform_driver_unregister(&msm_platform_driver);
msm_dp_unregister();
msm_hdmi_unregister();
adreno_unregister();
msm_edp_unregister();
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment