drm/i915: Setup DDI clk for MST on SKL

Set up the DDI->PLL mapping on SKL also for MST links. Might help make
MST operational on SKL.

v2: Rebased due to KBL
    Improve the patch subject, Jesse provided the new one

Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1439826380-18403-1-git-send-email-ville.syrjala@linux.intel.com
References: https://bugs.freedesktop.org/show_bug.cgi?id=91791
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
Ville Syrjälä 2015-08-17 18:46:20 +03:00
parent abfce94905
commit e404ba8d06
3 changed files with 32 additions and 27 deletions

View file

@ -2259,30 +2259,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
return DDI_BUF_TRANS_SELECT(level); return DDI_BUF_TRANS_SELECT(level);
} }
static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) void intel_ddi_clk_select(struct intel_encoder *encoder,
const struct intel_crtc_state *pipe_config)
{ {
struct drm_encoder *encoder = &intel_encoder->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_device *dev = encoder->dev; enum port port = intel_ddi_get_encoder_port(encoder);
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type;
int hdmi_level;
if (type == INTEL_OUTPUT_EDP) { if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); uint32_t dpll = pipe_config->ddi_pll_sel;
intel_edp_panel_on(intel_dp);
}
if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
uint32_t dpll = crtc->config->ddi_pll_sel;
uint32_t val; uint32_t val;
/* /*
* DPLL0 is used for eDP and is the only "private" DPLL (as * DPLL0 is used for eDP and is the only "private" DPLL (as
* opposed to shared) on SKL * opposed to shared) on SKL
*/ */
if (type == INTEL_OUTPUT_EDP) { if (encoder->type == INTEL_OUTPUT_EDP) {
WARN_ON(dpll != SKL_DPLL0); WARN_ON(dpll != SKL_DPLL0);
val = I915_READ(DPLL_CTRL1); val = I915_READ(DPLL_CTRL1);
@ -2290,7 +2281,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
DPLL_CTRL1_SSC(dpll) | DPLL_CTRL1_SSC(dpll) |
DPLL_CTRL1_LINK_RATE_MASK(dpll)); DPLL_CTRL1_LINK_RATE_MASK(dpll));
val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6); val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
I915_WRITE(DPLL_CTRL1, val); I915_WRITE(DPLL_CTRL1, val);
POSTING_READ(DPLL_CTRL1); POSTING_READ(DPLL_CTRL1);
@ -2306,10 +2297,28 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
I915_WRITE(DPLL_CTRL2, val); I915_WRITE(DPLL_CTRL2, val);
} else if (INTEL_INFO(dev)->gen < 9) { } else if (INTEL_INFO(dev_priv)->gen < 9) {
WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE); WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel); I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
} }
}
static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
{
struct drm_encoder *encoder = &intel_encoder->base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
enum port port = intel_ddi_get_encoder_port(intel_encoder);
int type = intel_encoder->type;
int hdmi_level;
if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_edp_panel_on(intel_dp);
}
intel_ddi_clk_select(intel_encoder, crtc->config);
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

View file

@ -173,20 +173,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
intel_mst->port = found->port; intel_mst->port = found->port;
if (intel_dp->active_mst_links == 0) { if (intel_dp->active_mst_links == 0) {
enum port port = intel_ddi_get_encoder_port(encoder); intel_ddi_clk_select(encoder, intel_crtc->config);
intel_dp_set_link_params(intel_dp, intel_crtc->config); intel_dp_set_link_params(intel_dp, intel_crtc->config);
/* FIXME: add support for SKL */
if (INTEL_INFO(dev)->gen < 9)
I915_WRITE(PORT_CLK_SEL(port),
intel_crtc->config->ddi_pll_sel);
intel_ddi_init_dp_buf_reg(&intel_dig_port->base); intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_start_link_train(intel_dp); intel_dp_start_link_train(intel_dp);
intel_dp_stop_link_train(intel_dp); intel_dp_stop_link_train(intel_dp);
} }

View file

@ -997,6 +997,8 @@ void intel_crt_init(struct drm_device *dev);
/* intel_ddi.c */ /* intel_ddi.c */
void intel_ddi_clk_select(struct intel_encoder *encoder,
const struct intel_crtc_state *pipe_config);
void intel_prepare_ddi(struct drm_device *dev); void intel_prepare_ddi(struct drm_device *dev);
void hsw_fdi_link_train(struct drm_crtc *crtc); void hsw_fdi_link_train(struct drm_crtc *crtc);
void intel_ddi_init(struct drm_device *dev, enum port port); void intel_ddi_init(struct drm_device *dev, enum port port);