drm/i915: add DP 1.2 MST support (v0.7)
This adds DP 1.2 MST support on Haswell systems. Notes: a) this reworks irq handling for DP MST ports, so that we can avoid the mode config locking in the current hpd handlers, as we need to process up/down msgs at a better time. Changes since v0.1: use PORT_PCH_HOTPLUG to detect short vs long pulses add a workqueue to deal with digital events as they can get blocked on the main workqueue beyong mode_config mutex fix a bunch of modeset checker warnings acks irqs in the driver cleanup the MST encoders Changes since v0.2: check irq status again in work handler move around bring up and tear down to fix DPMS on/off use path properties. Changes since v0.3: updates for mst apis more state checker fixes irq handling improvements fbcon handling support improved reference counting of link - fixes redocking. Changes since v0.4: handle gpu reset hpd reinit without oopsing check link status on HPD irqs fix suspend/resume Changes since v0.5: use proper functions to get max link/lane counts fix another checker backtrace - due to connectors disappearing. set output type in more places fro, unknown->displayport don't talk to devices if no HPD asserted check mst on short irqs only check link status properly rebase onto prepping irq changes. drop unsued force_act Changes since v0.6: cleanup unused struct entry. [airlied: fix some sparse warnings]. Reviewed-by: Todd Previte <tprevite@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_dp_mst_helper.h>
|
||||
|
||||
/**
|
||||
* _wait_for - magic (register) wait macro
|
||||
@@ -100,6 +100,7 @@
|
||||
#define INTEL_OUTPUT_EDP 8
|
||||
#define INTEL_OUTPUT_DSI 9
|
||||
#define INTEL_OUTPUT_UNKNOWN 10
|
||||
#define INTEL_OUTPUT_DP_MST 11
|
||||
|
||||
#define INTEL_DVO_CHIP_NONE 0
|
||||
#define INTEL_DVO_CHIP_LVDS 1
|
||||
@@ -207,6 +208,10 @@ struct intel_connector {
|
||||
/* since POLL and HPD connectors may use the same HPD line keep the native
|
||||
state of connector->polled in case hotplug storm detection changes it */
|
||||
u8 polled;
|
||||
|
||||
void *port; /* store this opaque as its illegal to dereference it */
|
||||
|
||||
struct intel_dp *mst_port;
|
||||
};
|
||||
|
||||
typedef struct dpll {
|
||||
@@ -351,6 +356,9 @@ struct intel_crtc_config {
|
||||
bool ips_enabled;
|
||||
|
||||
bool double_wide;
|
||||
|
||||
bool dp_encoder_is_mst;
|
||||
int pbn;
|
||||
};
|
||||
|
||||
struct intel_pipe_wm {
|
||||
@@ -506,6 +514,7 @@ struct intel_hdmi {
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
};
|
||||
|
||||
struct intel_dp_mst_encoder;
|
||||
#define DP_MAX_DOWNSTREAM_PORTS 0x10
|
||||
|
||||
/**
|
||||
@@ -545,8 +554,16 @@ struct intel_dp {
|
||||
unsigned long last_power_on;
|
||||
unsigned long last_backlight_off;
|
||||
bool use_tps3;
|
||||
bool can_mst; /* this port supports mst */
|
||||
bool is_mst;
|
||||
int active_mst_links;
|
||||
/* connector directly attached - won't be use for modeset in mst world */
|
||||
struct intel_connector *attached_connector;
|
||||
|
||||
/* mst connector list */
|
||||
struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
|
||||
struct drm_dp_mst_topology_mgr mst_mgr;
|
||||
|
||||
uint32_t (*get_aux_clock_divider)(struct intel_dp *dp, int index);
|
||||
/*
|
||||
* This function returns the value we have to program the AUX_CTL
|
||||
@@ -573,6 +590,13 @@ struct intel_digital_port {
|
||||
bool (*hpd_pulse)(struct intel_digital_port *, bool);
|
||||
};
|
||||
|
||||
struct intel_dp_mst_encoder {
|
||||
struct intel_encoder base;
|
||||
enum pipe pipe;
|
||||
struct intel_digital_port *primary;
|
||||
void *port; /* store this opaque as its illegal to dereference it */
|
||||
};
|
||||
|
||||
static inline int
|
||||
vlv_dport_to_channel(struct intel_digital_port *dport)
|
||||
{
|
||||
@@ -657,6 +681,12 @@ enc_to_dig_port(struct drm_encoder *encoder)
|
||||
return container_of(encoder, struct intel_digital_port, base.base);
|
||||
}
|
||||
|
||||
static inline struct intel_dp_mst_encoder *
|
||||
enc_to_mst(struct drm_encoder *encoder)
|
||||
{
|
||||
return container_of(encoder, struct intel_dp_mst_encoder, base.base);
|
||||
}
|
||||
|
||||
static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
|
||||
{
|
||||
return &enc_to_dig_port(encoder)->dp;
|
||||
@@ -719,6 +749,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_config *pipe_config);
|
||||
|
||||
void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
|
||||
void intel_ddi_clock_get(struct intel_encoder *encoder,
|
||||
struct intel_crtc_config *pipe_config);
|
||||
void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
|
||||
|
||||
/* intel_display.c */
|
||||
const char *intel_output_name(int output);
|
||||
@@ -871,6 +904,15 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
|
||||
void intel_edp_psr_exit(struct drm_device *dev);
|
||||
void intel_edp_psr_init(struct drm_device *dev);
|
||||
|
||||
int intel_dp_handle_hpd_irq(struct intel_digital_port *digport, bool long_hpd);
|
||||
void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
|
||||
void intel_dp_mst_suspend(struct drm_device *dev);
|
||||
void intel_dp_mst_resume(struct drm_device *dev);
|
||||
int intel_dp_max_link_bw(struct intel_dp *intel_dp);
|
||||
void intel_dp_hot_plug(struct intel_encoder *intel_encoder);
|
||||
/* intel_dp_mst.c */
|
||||
int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
|
||||
void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
|
||||
/* intel_dsi.c */
|
||||
void intel_dsi_init(struct drm_device *dev);
|
||||
|
||||
|
Reference in New Issue
Block a user