Пример #1
0
void mainboard_train_link(struct intel_dp *intel_dp)
{
	u8 read_val;
	u8 link_status[DP_LINK_STATUS_SIZE];

	gtt_write(DP_TP_CTL(intel_dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE);
	gtt_write(DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH |0x80000011);

	intel_dp_get_training_pattern(intel_dp, &read_val);
	intel_dp_set_training_pattern(intel_dp, DP_TRAINING_PATTERN_1 | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH);
	intel_dp_get_lane_count(intel_dp, &read_val);
	intel_dp_set_training_lane0(intel_dp, DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0);
	intel_dp_get_link_status(intel_dp, link_status);

	gtt_write(DP_TP_CTL(intel_dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT2);

	intel_dp_get_training_pattern(intel_dp, &read_val);
	intel_dp_set_training_pattern(intel_dp, DP_TRAINING_PATTERN_2 | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH);
	intel_dp_get_link_status(intel_dp, link_status);
	intel_dp_get_lane_align_status(intel_dp, &read_val);
	intel_dp_get_training_pattern(intel_dp, &read_val);
	intel_dp_set_training_pattern(intel_dp, DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH);
}
Пример #2
0
void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, int port)
{
	int wait = 0;
	uint32_t val;

	if (io_i915_read32(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
		val = io_i915_read32(DDI_BUF_CTL(port));
		if (val & DDI_BUF_CTL_ENABLE) {
			val &= ~DDI_BUF_CTL_ENABLE;
			io_i915_write32(DDI_BUF_CTL(port), val);
			wait = 1;
		}

		val = io_i915_read32(DP_TP_CTL(port));
		val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
		val |= DP_TP_CTL_LINK_TRAIN_PAT1;
		io_i915_write32(DP_TP_CTL(port), val);
		//POSTING_READ(DP_TP_CTL(port));

		if (wait)
			intel_wait_ddi_buf_idle(port);
	}

	val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST |
	      DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
	if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
		val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
	io_i915_write32(DP_TP_CTL(port), val);
	//POSTING_READ(DP_TP_CTL(port));

	intel_dp->DP |= DDI_BUF_CTL_ENABLE;
	io_i915_write32(DDI_BUF_CTL(port), intel_dp->DP);
	//POSTING_READ(DDI_BUF_CTL(port));

	udelay(600);
}
Пример #3
0
void hsw_fdi_link_train(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	u32 temp, i, rx_ctl_val;

	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
	 * mode set "sequence for CRT port" document:
	 * - TP1 to TP2 time with the default value
	 * - FDI delay to 90h
	 *
	 * WaFDIAutoLinkSetTimingOverrride:hsw
	 */
	I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
				  FDI_RX_PWRDN_LANE0_VAL(2) |
				  FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);

	/* Enable the PCH Receiver FDI PLL */
	rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
		     FDI_RX_PLL_ENABLE |
		     FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
	POSTING_READ(_FDI_RXA_CTL);
	udelay(220);

	/* Switch from Rawclk to PCDclk */
	rx_ctl_val |= FDI_PCDCLK;
	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);

	/* Configure Port Clock Select */
	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel);

	/* Start the training iterating through available voltages and emphasis,
	 * testing each value twice. */
	for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) {
		/* Configure DP_TP_CTL with auto-training */
		I915_WRITE(DP_TP_CTL(PORT_E),
					DP_TP_CTL_FDI_AUTOTRAIN |
					DP_TP_CTL_ENHANCED_FRAME_ENABLE |
					DP_TP_CTL_LINK_TRAIN_PAT1 |
					DP_TP_CTL_ENABLE);

		/* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
		 * DDI E does not support port reversal, the functionality is
		 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
		 * port reversal bit */
		I915_WRITE(DDI_BUF_CTL(PORT_E),
			   DDI_BUF_CTL_ENABLE |
			   ((intel_crtc->config.fdi_lanes - 1) << 1) |
			   hsw_ddi_buf_ctl_values[i / 2]);
		POSTING_READ(DDI_BUF_CTL(PORT_E));

		udelay(600);

		/* Program PCH FDI Receiver TU */
		I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64));

		/* Enable PCH FDI Receiver with auto-training */
		rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
		I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
		POSTING_READ(_FDI_RXA_CTL);

		/* Wait for FDI receiver lane calibration */
		udelay(30);

		/* Unset FDI_RX_MISC pwrdn lanes */
		temp = I915_READ(_FDI_RXA_MISC);
		temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
		I915_WRITE(_FDI_RXA_MISC, temp);
		POSTING_READ(_FDI_RXA_MISC);

		/* Wait for FDI auto training time */
		udelay(5);

		temp = I915_READ(DP_TP_STATUS(PORT_E));
		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
			DRM_DEBUG_KMS("FDI link training done on step %d\n", i);

			/* Enable normal pixel sending for FDI */
			I915_WRITE(DP_TP_CTL(PORT_E),
				   DP_TP_CTL_FDI_AUTOTRAIN |
				   DP_TP_CTL_LINK_TRAIN_NORMAL |
				   DP_TP_CTL_ENHANCED_FRAME_ENABLE |
				   DP_TP_CTL_ENABLE);

			return;
		}

		temp = I915_READ(DDI_BUF_CTL(PORT_E));
		temp &= ~DDI_BUF_CTL_ENABLE;
		I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
		POSTING_READ(DDI_BUF_CTL(PORT_E));

		/* Disable DP_TP_CTL and FDI_RX_CTL and retry */
		temp = I915_READ(DP_TP_CTL(PORT_E));
		temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
		temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
		I915_WRITE(DP_TP_CTL(PORT_E), temp);
		POSTING_READ(DP_TP_CTL(PORT_E));

		intel_wait_ddi_buf_idle(dev_priv, PORT_E);

		rx_ctl_val &= ~FDI_RX_ENABLE;
		I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
		POSTING_READ(_FDI_RXA_CTL);

		/* Reset FDI_RX_MISC pwrdn lanes */
		temp = I915_READ(_FDI_RXA_MISC);
		temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
		temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
		I915_WRITE(_FDI_RXA_MISC, temp);
		POSTING_READ(_FDI_RXA_MISC);
	}

	DRM_ERROR("FDI link training failed!\n");
}
Пример #4
0
void runio(struct intel_dp *dp)
{
	u8 read_val;

	intel_dp_wait_panel_power_control(0xabcd0008);

	/* vbios spins at this point. Some haswell weirdness? */
	intel_dp_wait_panel_power_control(0xabcd0008);

	/* This should be a function like intel_panel_enable_backlight
	   However, we are not sure how the value 0x3a9 comes up.
	   It has to do something with PWM frequency */
	gtt_write(BLC_PWM_CPU_CTL,0x03a903a9);
	gtt_write(BLC_PWM_PCH_CTL2,0x03a903a9);
	gtt_write(BLC_PWM_PCH_CTL1,BLM_PCH_PWM_ENABLE);

	gtt_write(DEIIR,0x00008000);
	intel_dp_wait_reg(DEIIR, 0x00000000);

	gtt_write(DSPSTRIDE(dp->plane),dp->stride);

	intel_dp_sink_dpms(dp, 0);

	intel_dp_get_max_downspread(dp, &read_val);

	intel_dp_set_m_n_regs(dp);

	intel_dp_set_resolution(dp);

	gtt_write(PIPESRC(dp->pipe),dp->pipesrc);
	gtt_write(PIPECONF(dp->transcoder),0x00000000);
	gtt_write(PCH_TRANSCONF(dp->pipe),0x00000000);

	mainboard_set_port_clk_dp(dp);
	gtt_write(DSPSTRIDE(dp->plane),dp->stride);
	gtt_write(DSPCNTR(dp->plane),DISPLAY_PLANE_ENABLE|DISPPLANE_BGRX888);
	gtt_write(DEIIR,0x00000080);

	gtt_write(TRANS_DDI_FUNC_CTL_EDP,dp->flags);
	gtt_write(PIPECONF(dp->transcoder),PIPECONF_ENABLE|PIPECONF_DITHER_EN);

	intel_dp_wait_panel_power_control(0xabcd000a);

	/* what is this doing? Not sure yet. */
	intel_dp_i2c_write(dp, 0x0);
	intel_dp_i2c_read(dp, &read_val);
	intel_dp_i2c_write(dp, 0x04);
	intel_dp_i2c_read(dp, &read_val);
	intel_dp_i2c_write(dp, 0x7e);
	intel_dp_i2c_read(dp, &read_val);

	/* this needs to be a call to a function */
	gtt_write(DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x00000091);
	gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE);
	gtt_write(DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x80040091);

	/* we may need to move these *after* power well power up and *before* PCH_PP_CONTROL in gma.c */
	gtt_write(PCH_PP_ON_DELAYS, PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x1<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x0001000a);
	gtt_write(PCH_PP_ON_DELAYS, PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x7d0<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x07d0000a);

	intel_dp_set_bw(dp);
	intel_dp_set_lane_count(dp);

	mainboard_train_link(dp);

	/* need a function: intel_ddi_set_tp or similar */
	gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_IDLE);
	gtt_write(DP_TP_CTL(dp->port),DP_TP_CTL_ENABLE | DP_TP_CTL_ENHANCED_FRAME_ENABLE | DP_TP_CTL_LINK_TRAIN_NORMAL);

	gtt_write(BLC_PWM_CPU_CTL,0x03a903a9);
	gtt_write(BLC_PWM_PCH_CTL2,0x03a903a9);
	gtt_write(BLC_PWM_PCH_CTL1,0x80000000);

	/* some of this is not needed. */
	gtt_write(DIGITAL_PORT_HOTPLUG_CNTRL, DIGITAL_PORTA_HOTPLUG_ENABLE );

	gtt_write(SDEIIR,0x00000000);
	gtt_write(DEIIR,0x00000000);
	gtt_write(DEIIR,0x00008000);
	intel_dp_wait_reg(DEIIR, 0x00000000);

	gtt_write(DSPSTRIDE(dp->plane),dp->stride);
	gtt_write(PIPESRC(dp->pipe),dp->pipesrc);

	gtt_write(DEIIR,0x00000080);
	intel_dp_wait_reg(DEIIR, 0x00000000);

	gtt_write(DSPSTRIDE(dp->plane),dp->stride);
	gtt_write(DSPCNTR(dp->plane),DISPLAY_PLANE_ENABLE | DISPPLANE_BGRX888);

	gtt_write(PCH_PP_CONTROL,EDP_BLC_ENABLE | PANEL_POWER_RESET | PANEL_POWER_ON);

	gtt_write(SDEIIR,0x00000000);
	gtt_write(SDEIIR,0x00000000);
	gtt_write(DEIIR,0x00000000);
}
Пример #5
0
void hsw_fdi_link_train(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	u32 reg, temp, i;

	/* Configure CPU PLL, wait for warmup */
	I915_WRITE(SPLL_CTL,
			SPLL_PLL_ENABLE |
			SPLL_PLL_FREQ_1350MHz |
			SPLL_PLL_SCC);

	/* Use SPLL to drive the output when in FDI mode */
	I915_WRITE(PORT_CLK_SEL(PORT_E),
			PORT_CLK_SEL_SPLL);
	I915_WRITE(PIPE_CLK_SEL(pipe),
			PIPE_CLK_SEL_PORT(PORT_E));

	DELAY(20);

	/* Start the training iterating through available voltages and emphasis */
	for (i=0; i < DRM_ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) {
		/* Configure DP_TP_CTL with auto-training */
		I915_WRITE(DP_TP_CTL(PORT_E),
					DP_TP_CTL_FDI_AUTOTRAIN |
					DP_TP_CTL_ENHANCED_FRAME_ENABLE |
					DP_TP_CTL_LINK_TRAIN_PAT1 |
					DP_TP_CTL_ENABLE);

		/* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
		temp = I915_READ(DDI_BUF_CTL(PORT_E));
		temp = (temp & ~DDI_BUF_EMP_MASK);
		I915_WRITE(DDI_BUF_CTL(PORT_E),
				temp |
				DDI_BUF_CTL_ENABLE |
				DDI_PORT_WIDTH_X2 |
				hsw_ddi_buf_ctl_values[i]);

		DELAY(600);

		/* Enable CPU FDI Receiver with auto-training */
		reg = FDI_RX_CTL(pipe);
		I915_WRITE(reg,
				I915_READ(reg) |
					FDI_LINK_TRAIN_AUTO |
					FDI_RX_ENABLE |
					FDI_LINK_TRAIN_PATTERN_1_CPT |
					FDI_RX_ENHANCE_FRAME_ENABLE |
					FDI_PORT_WIDTH_2X_LPT |
					FDI_RX_PLL_ENABLE);
		POSTING_READ(reg);
		DELAY(100);

		temp = I915_READ(DP_TP_STATUS(PORT_E));
		if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
			DRM_DEBUG_DRIVER("BUF_CTL training done on %d step\n", i);

			/* Enable normal pixel sending for FDI */
			I915_WRITE(DP_TP_CTL(PORT_E),
						DP_TP_CTL_FDI_AUTOTRAIN |
						DP_TP_CTL_LINK_TRAIN_NORMAL |
						DP_TP_CTL_ENHANCED_FRAME_ENABLE |
						DP_TP_CTL_ENABLE);

			/* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */
			temp = I915_READ(DDI_FUNC_CTL(pipe));
			temp &= ~PIPE_DDI_PORT_MASK;
			temp |= PIPE_DDI_SELECT_PORT(PORT_E) |
					PIPE_DDI_MODE_SELECT_FDI |
					PIPE_DDI_FUNC_ENABLE |
					PIPE_DDI_PORT_WIDTH_X2;
			I915_WRITE(DDI_FUNC_CTL(pipe),
					temp);
			break;
		} else {
			DRM_ERROR("Error training BUF_CTL %d\n", i);

			/* Disable DP_TP_CTL and FDI_RX_CTL) and retry */
			I915_WRITE(DP_TP_CTL(PORT_E),
					I915_READ(DP_TP_CTL(PORT_E)) &
						~DP_TP_CTL_ENABLE);
			I915_WRITE(FDI_RX_CTL(pipe),
					I915_READ(FDI_RX_CTL(pipe)) &
						~FDI_RX_PLL_ENABLE);
			continue;
		}
	}

	DRM_DEBUG_KMS("FDI train done.\n");
}