Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e404ba8d authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

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: default avatarVille 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: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent abfce949
Loading
Loading
Loading
Loading
+29 −20
Original line number Diff line number Diff line
@@ -2259,30 +2259,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
	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_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);
	}
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum port port = intel_ddi_get_encoder_port(encoder);

	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
		uint32_t dpll = crtc->config->ddi_pll_sel;
	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
		uint32_t dpll = pipe_config->ddi_pll_sel;
		uint32_t val;

		/*
		 * DPLL0 is used for eDP and is the only "private" DPLL (as
		 * opposed to shared) on SKL
		 */
		if (type == INTEL_OUTPUT_EDP) {
		if (encoder->type == INTEL_OUTPUT_EDP) {
			WARN_ON(dpll != SKL_DPLL0);

			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) |
				 DPLL_CTRL1_SSC(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);
			POSTING_READ(DPLL_CTRL1);
@@ -2306,11 +2297,29 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)

		I915_WRITE(DPLL_CTRL2, val);

	} else if (INTEL_INFO(dev)->gen < 9) {
		WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
		I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
	} else if (INTEL_INFO(dev_priv)->gen < 9) {
		WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
		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) {
		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

+1 −7
Original line number Diff line number Diff line
@@ -173,20 +173,14 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
	intel_mst->port = found->port;

	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);

		/* 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_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);


		intel_dp_start_link_train(intel_dp);
		intel_dp_stop_link_train(intel_dp);
	}
+2 −0
Original line number Diff line number Diff line
@@ -997,6 +997,8 @@ void intel_crt_init(struct drm_device *dev);


/* 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 hsw_fdi_link_train(struct drm_crtc *crtc);
void intel_ddi_init(struct drm_device *dev, enum port port);