예제 #1
0
파일: intel_psr.c 프로젝트: 383530895/linux
static void intel_psr_write_vsc(struct intel_dp *intel_dp,
				    struct edp_vsc_psr *vsc_psr)
{
	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
	struct drm_device *dev = dig_port->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder);
	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder);
	uint32_t *data = (uint32_t *) vsc_psr;
	unsigned int i;

	/* As per BSPec (Pipe Video Data Island Packet), we need to disable
	   the video DIP being updated before program video DIP data buffer
	   registers for DIP being updated. */
	I915_WRITE(ctl_reg, 0);
	POSTING_READ(ctl_reg);

	for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) {
		if (i < sizeof(struct edp_vsc_psr))
			I915_WRITE(data_reg + i, *data++);
		else
			I915_WRITE(data_reg + i, 0);
	}

	I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW);
	POSTING_READ(ctl_reg);
}
예제 #2
0
파일: intel_hdmi.c 프로젝트: Andiry/pmfs
static void ibx_set_infoframes(struct drm_encoder *encoder,
			       struct drm_display_mode *adjusted_mode)
{
	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
	u32 reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
	u32 val = I915_READ(reg);
	u32 port;

	assert_hdmi_port_disabled(intel_hdmi);

	/* See the big comment in g4x_set_infoframes() */
	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;

	if (!intel_hdmi->has_hdmi_sink) {
		if (!(val & VIDEO_DIP_ENABLE))
			return;
		val &= ~VIDEO_DIP_ENABLE;
		I915_WRITE(reg, val);
		POSTING_READ(reg);
		return;
	}

	switch (intel_dig_port->port) {
	case PORT_B:
		port = VIDEO_DIP_PORT_B;
		break;
	case PORT_C:
		port = VIDEO_DIP_PORT_C;
		break;
	case PORT_D:
		port = VIDEO_DIP_PORT_D;
		break;
	default:
		BUG();
		return;
	}

	if (port != (val & VIDEO_DIP_PORT_MASK)) {
		if (val & VIDEO_DIP_ENABLE) {
			val &= ~VIDEO_DIP_ENABLE;
			I915_WRITE(reg, val);
			POSTING_READ(reg);
		}
		val &= ~VIDEO_DIP_PORT_MASK;
		val |= port;
	}

	val |= VIDEO_DIP_ENABLE;
	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
		 VIDEO_DIP_ENABLE_GCP);

	I915_WRITE(reg, val);
	POSTING_READ(reg);

	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
	intel_hdmi_set_spd_infoframe(encoder);
}
예제 #3
0
int dsi_vc_dcs_read(struct intel_dsi *intel_dsi, int channel, u8 dcs_cmd,
		    u8 *buf, int buflen)
{
	struct drm_encoder *encoder = &intel_dsi->base.base;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	enum pipe pipe = intel_crtc->pipe;
	u32 mask;
	int ret;

	/*
	 * XXX: should issue multiple read requests and reads if request is
	 * longer than MIPI_MAX_RETURN_PKT_SIZE
	 */

	I915_WRITE(MIPI_INTR_STAT(pipe), GEN_READ_DATA_AVAIL);

	ret = dsi_vc_dcs_send_read_request(intel_dsi, channel, dcs_cmd);
	if (ret)
		return ret;

	mask = GEN_READ_DATA_AVAIL;
	if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 50))
		DRM_ERROR("Timeout waiting for read data.\n");

	ret = dsi_read_data_return(intel_dsi, buf, buflen);
	if (ret < 0)
		return ret;

	if (ret != buflen)
		return -EIO;

	return 0;
}
예제 #4
0
static void intel_dsi_device_ready(struct intel_encoder *encoder)
{
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	int pipe = intel_crtc->pipe;
	u32 val;

	DRM_DEBUG_KMS("\n");

	mutex_lock(&dev_priv->dpio_lock);
	/* program rcomp for compliance, reduce from 50 ohms to 45 ohms
	 * needed everytime after power gate */
	vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
	mutex_unlock(&dev_priv->dpio_lock);

	/* bandgap reset is needed after everytime we do power gate */
	band_gap_reset(dev_priv);

	I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
	usleep_range(2500, 3000);

	val = I915_READ(MIPI_PORT_CTRL(pipe));
	I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
	usleep_range(1000, 1500);

	I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
	usleep_range(2500, 3000);

	I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
	usleep_range(2500, 3000);
}
예제 #5
0
static void intel_psr_write_vsc(struct intel_dp *intel_dp,
				const struct edp_vsc_psr *vsc_psr)
{
	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
	struct drm_device *dev = dig_port->base.base.dev;
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
	i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
	uint32_t *data = (uint32_t *) vsc_psr;
	unsigned int i;

	/* As per BSPec (Pipe Video Data Island Packet), we need to disable
	   the video DIP being updated before program video DIP data buffer
	   registers for DIP being updated. */
	I915_WRITE(ctl_reg, 0);
	POSTING_READ(ctl_reg);

	for (i = 0; i < sizeof(*vsc_psr); i += 4) {
		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
						   i >> 2), *data);
		data++;
	}
	for (; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4)
		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
						   i >> 2), 0);

	I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW);
	POSTING_READ(ctl_reg);
}
int intel_configure_dsi_pll(struct intel_dsi *intel_dsi,
		struct drm_display_mode *mode)
{
	struct drm_i915_private *dev_priv =
			intel_dsi->base.base.dev->dev_private;
	struct drm_encoder *encoder = &(intel_dsi->base.base);
	struct intel_connector *intel_connector = intel_dsi->attached_connector;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct intel_crtc_config *config = &intel_crtc->config;
	int ret;

	DRM_DEBUG_KMS("\n");

	ret = intel_calculate_dsi_pll_mnp(intel_dsi, mode,
					&config->dsi_mnp, intel_dsi->dsi_clock_freq);
	if (ret < 0)
		return ret;

	/* In case of DRRS, Calculating the divider values for downclock_mode */
	if (intel_connector->panel.downclock_avail &&
		dev_priv->drrs_state.type >= SEAMLESS_DRRS_SUPPORT) {
		ret = intel_calculate_dsi_pll_mnp(intel_dsi,
			intel_connector->panel.downclock_mode, &config->dsi_mnp2, 0);
		if (ret < 0)
			return ret;
	}


	intel_configure_dsi_pll_reg(dev_priv, &config->dsi_mnp, intel_dsi, false);


	return 0;
}
static void intel_dsi_pre_enable(struct intel_encoder *encoder)
{
	struct drm_device *dev = encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	int pipe = intel_crtc->pipe;
	DRM_DEBUG_KMS("\n");

	intel_enable_dsi_pll(intel_dsi);

	if (is_cmd_mode(intel_dsi)) {
		/* XXX: Implement me */
		I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
	}
	else {
		intel_dsi->hs = 0;
		dpi_send_cmd(intel_dsi, TURN_ON);
		usleep_range(1000, 1500);
		if (intel_dsi->dev.dev_ops->enable)
			intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);

		intel_dsi_port_enable(encoder);
	}
}
예제 #8
0
파일: intel_hdmi.c 프로젝트: Andiry/pmfs
static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
					 struct drm_display_mode *adjusted_mode)
{
	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct dip_infoframe avi_if = {
		.type = DIP_TYPE_AVI,
		.ver = DIP_VERSION_AVI,
		.len = DIP_LEN_AVI,
	};

	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
		avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;

	if (intel_hdmi->rgb_quant_range_selectable) {
		if (intel_crtc->config.limited_color_range)
			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
		else
			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
	}

	avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode);

	intel_set_infoframe(encoder, &avi_if);
}
예제 #9
0
/*
 * send a video mode command
 *
 * XXX: commands with data in MIPI_DPI_DATA?
 */
int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
{
	struct drm_encoder *encoder = &intel_dsi->base.base;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	enum pipe pipe = intel_crtc->pipe;
	u32 mask;

	/* XXX: pipe, hs */
	if (hs)
		cmd &= ~DPI_LP_MODE;
	else
		cmd |= DPI_LP_MODE;

	/* clear bit */
	I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);

	/* XXX: old code skips write if control unchanged */
	if (cmd == I915_READ(MIPI_DPI_CONTROL(pipe)))
		DRM_ERROR("Same special packet %02x twice in a row.\n", cmd);

	I915_WRITE(MIPI_DPI_CONTROL(pipe), cmd);

	mask = SPL_PKT_SENT_INTERRUPT;
	if (wait_for((I915_READ(MIPI_INTR_STAT(pipe)) & mask) == mask, 100))
		DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd);

	return 0;
}
예제 #10
0
파일: intel_hdmi.c 프로젝트: AllenDou/linux
static void hsw_set_infoframes(struct drm_encoder *encoder,
			       struct drm_display_mode *adjusted_mode)
{
	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
	u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
	u32 val = I915_READ(reg);

	assert_hdmi_port_disabled(intel_hdmi);

	if (!intel_hdmi->has_hdmi_sink) {
		I915_WRITE(reg, 0);
		POSTING_READ(reg);
		return;
	}

	val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
		 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW);

	I915_WRITE(reg, val);
	POSTING_READ(reg);

	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
	intel_hdmi_set_spd_infoframe(encoder);
}
예제 #11
0
static void intel_dsi_disable(struct intel_encoder *encoder)
{
	struct drm_device *dev = encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	int pipe = intel_crtc->pipe;
	u32 temp;

	DRM_DEBUG_KMS("\n");

	if (is_vid_mode(intel_dsi)) {
		dpi_send_cmd(intel_dsi, SHUTDOWN);
		msleep(10);

		/* de-assert ip_tg_enable signal */
		temp = I915_READ(MIPI_PORT_CTRL(pipe));
		I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE);
		POSTING_READ(MIPI_PORT_CTRL(pipe));

		msleep(2);
	}

	/* if disable packets are sent before sending shutdown packet then in
	 * some next enable sequence send turn on packet error is observed */
	if (intel_dsi->dev.dev_ops->disable)
		intel_dsi->dev.dev_ops->disable(&intel_dsi->dev);
}
예제 #12
0
static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
{
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	int pipe = intel_crtc->pipe;
	u32 val;

	DRM_DEBUG_KMS("\n");

	I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
	usleep_range(2000, 2500);

	I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
	usleep_range(2000, 2500);

	I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
	usleep_range(2000, 2500);

	val = I915_READ(MIPI_PORT_CTRL(pipe));
	I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
	usleep_range(1000, 1500);

	if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT)
					== 0x00000), 30))
		DRM_ERROR("DSI LP not going Low\n");

	I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
	usleep_range(2000, 2500);

	vlv_disable_dsi_pll(encoder);
}
예제 #13
0
파일: intel_hdmi.c 프로젝트: AllenDou/linux
static void vlv_set_infoframes(struct drm_encoder *encoder,
			       struct drm_display_mode *adjusted_mode)
{
	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
	u32 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
	u32 val = I915_READ(reg);

	assert_hdmi_port_disabled(intel_hdmi);

	/* See the big comment in g4x_set_infoframes() */
	val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;

	if (!intel_hdmi->has_hdmi_sink) {
		if (!(val & VIDEO_DIP_ENABLE))
			return;
		val &= ~VIDEO_DIP_ENABLE;
		I915_WRITE(reg, val);
		POSTING_READ(reg);
		return;
	}

	val |= VIDEO_DIP_ENABLE;
	val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
		 VIDEO_DIP_ENABLE_GCP);

	I915_WRITE(reg, val);
	POSTING_READ(reg);

	intel_hdmi_set_avi_infoframe(encoder, adjusted_mode);
	intel_hdmi_set_spd_infoframe(encoder);
}
예제 #14
0
static void intel_hdmi_mode_set(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc = encoder->crtc;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	struct intel_output *intel_output = enc_to_intel_output(encoder);
	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
	u32 sdvox;

	sdvox = SDVO_ENCODING_HDMI |
		SDVO_BORDER_ENABLE |
		SDVO_VSYNC_ACTIVE_HIGH |
		SDVO_HSYNC_ACTIVE_HIGH;

	if (hdmi_priv->has_hdmi_sink)
		sdvox |= SDVO_AUDIO_ENABLE;

	if (intel_crtc->pipe == 1)
		sdvox |= SDVO_PIPE_B_SELECT;

	I915_WRITE(hdmi_priv->sdvox_reg, sdvox);
	POSTING_READ(hdmi_priv->sdvox_reg);
}
예제 #15
0
static void hsw_write_infoframe(struct drm_encoder *encoder,
                                struct dip_infoframe *frame)
{
    uint32_t *data = (uint32_t *)frame;
    struct drm_device *dev = encoder->dev;
    struct drm_i915_private *dev_priv = dev->dev_private;
    struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
    u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe);
    u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe);
    unsigned int i, len = DIP_HEADER_SIZE + frame->len;
    u32 val = I915_READ(ctl_reg);

    if (data_reg == 0)
        return;

    val &= ~hsw_infoframe_enable(frame);
    I915_WRITE(ctl_reg, val);

    mmiowb();
    for (i = 0; i < len; i += 4) {
        I915_WRITE(data_reg + i, *data);
        data++;
    }
    /* Write every possible data byte to force correct ECC calculation. */
    for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
        I915_WRITE(data_reg + i, 0);
    mmiowb();

    val |= hsw_infoframe_enable(frame);
    I915_WRITE(ctl_reg, val);
    POSTING_READ(ctl_reg);
}
예제 #16
0
static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
					 struct drm_display_mode *adjusted_mode)
{
	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	union hdmi_infoframe frame;
	int ret;

	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
						       adjusted_mode);
	if (ret < 0) {
		DRM_ERROR("couldn't fill AVI infoframe\n");
		return;
	}

	if (intel_hdmi->rgb_quant_range_selectable) {
		if (intel_crtc->config.limited_color_range)
			frame.avi.quantization_range =
				HDMI_QUANTIZATION_RANGE_LIMITED;
		else
			frame.avi.quantization_range =
				HDMI_QUANTIZATION_RANGE_FULL;
	}

	intel_write_infoframe(encoder, &frame);
}
예제 #17
0
static void hsw_write_infoframe(struct drm_encoder *encoder,
				enum hdmi_infoframe_type type,
				const uint8_t *frame, ssize_t len)
{
	uint32_t *data = (uint32_t *)frame;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
	u32 data_reg;
	int i;
	u32 val = I915_READ(ctl_reg);

	data_reg = hsw_infoframe_data_reg(type,
					  intel_crtc->config.cpu_transcoder);
	if (data_reg == 0)
		return;

	val &= ~hsw_infoframe_enable(type);
	I915_WRITE(ctl_reg, val);

	mmiowb();
	for (i = 0; i < len; i += 4) {
		I915_WRITE(data_reg + i, *data);
		data++;
	}
	/* Write every possible data byte to force correct ECC calculation. */
	for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
		I915_WRITE(data_reg + i, 0);
	mmiowb();

	val |= hsw_infoframe_enable(type);
	I915_WRITE(ctl_reg, val);
	POSTING_READ(ctl_reg);
}
예제 #18
0
static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
{
	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
	struct drm_device *dev = encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc =
		to_intel_crtc(encoder->base.crtc);
	int port = vlv_dport_to_channel(dport);
	int pipe = intel_crtc->pipe;

	if (!IS_VALLEYVIEW(dev))
		return;

	/* Program Tx lane resets to default */
	mutex_lock(&dev_priv->dpio_lock);
	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
			 DPIO_PCS_TX_LANE2_RESET |
			 DPIO_PCS_TX_LANE1_RESET);
	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
			 DPIO_PCS_CLK_SOFT_RESET);

	/* Fix up inter-pair skew failure */
	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
	vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
	vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);

	vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port),
			 0x00002000);
	vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port),
			 DPIO_TX_OCALINIT_EN);
	mutex_unlock(&dev_priv->dpio_lock);
}
예제 #19
0
static void intel_dsi_enable(struct intel_encoder *encoder)
{
	struct drm_device *dev = encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	int pipe = intel_crtc->pipe;
	u32 temp;

	DRM_DEBUG_KMS("\n");

	if (is_cmd_mode(intel_dsi))
		I915_WRITE(MIPI_MAX_RETURN_PKT_SIZE(pipe), 8 * 4);
	else {
		msleep(20); /* XXX */
		dpi_send_cmd(intel_dsi, TURN_ON);
		msleep(100);

		/* assert ip_tg_enable signal */
		temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK;
		temp = temp | intel_dsi->port_bits;
		I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE);
		POSTING_READ(MIPI_PORT_CTRL(pipe));
	}

	if (intel_dsi->dev.dev_ops->enable)
		intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
}
예제 #20
0
static int dsi_read_data_return(struct intel_dsi *intel_dsi,
				u8 *buf, int buflen)
{
	struct drm_encoder *encoder = &intel_dsi->base.base;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	enum pipe pipe = intel_crtc->pipe;
	int i, len = 0;
	u32 data_reg, val;

	if (intel_dsi->hs) {
		data_reg = MIPI_HS_GEN_DATA(pipe);
	} else {
		data_reg = MIPI_LP_GEN_DATA(pipe);
	}

	while (len < buflen) {
		val = I915_READ(data_reg);
		for (i = 0; i < 4 && len < buflen; i++, len++)
			buf[len] = val >> 8 * i;
	}

	return len;
}
void intel_dsi_port_enable(struct intel_encoder *encoder)
{
	struct drm_device *dev = encoder->base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	int pipe = intel_crtc->pipe;
	u32 val, port_control = 0;

	if (intel_dsi->dual_link) {
		port_control = (intel_dsi->dual_link - 1)
						<< DUAL_LINK_MODE_SHIFT;
		if (pipe == PIPE_A)
			port_control |= LANE_CONFIGURATION_DUAL_LINK_A;
		else
			port_control |= LANE_CONFIGURATION_DUAL_LINK_B;

		/*Pixel overlap count; only for VLV CO stepping */
		if (IS_VALLEYVIEW_C0(dev) && (intel_dsi->dual_link & MIPI_DUAL_LINK_FRONT_BACK)) {
			val = I915_READ(VLV_CHICKEN_3);
			val &= ~PIXEL_OVERLAP_CNT_MASK |
				intel_dsi->pixel_overlap <<
				PIXEL_OVERLAP_CNT_SHIFT;
			I915_WRITE(VLV_CHICKEN_3, val);
		}

		/* Port A */
		val = I915_READ(MIPI_PORT_CTRL(0));
		val = val | port_control;
		I915_WRITE(MIPI_PORT_CTRL(0), val | DPI_ENABLE);

		if (!IS_VALLEYVIEW_C0(dev)) {
			/* for stepping before C0; we need to enable
			* PORTC explicitly. From C0 onwards enable PORT A
			* also enabled PORT C for dual link
			*/
			val = I915_READ(MIPI_PORT_CTRL(1));
			I915_WRITE(MIPI_PORT_CTRL(1), val | DPI_ENABLE);
		} else {
			if (intel_crtc->config.dither) {
				val = I915_READ(MIPI_PORT_CTRL(0));
				val = val | DITHERING_ENABLE;
				I915_WRITE(MIPI_PORT_CTRL(0), val);
				val = I915_READ(MIPI_PORT_CTRL(1));
				val = val | DITHERING_ENABLE;
				I915_WRITE(MIPI_PORT_CTRL(1), val);
			}
		}
		usleep_range(2000, 2500);
	} else {
		val = I915_READ(MIPI_PORT_CTRL(pipe));
		val = val | port_control;
		if (intel_crtc->config.dither && IS_VALLEYVIEW_C0(dev))
			val |= DITHERING_ENABLE;
		I915_WRITE(MIPI_PORT_CTRL(pipe), val | DPI_ENABLE);
		usleep_range(2000, 2500);
	}

}
예제 #22
0
void intel_disable_plane(struct intel_plane *plane,
			 const struct intel_crtc_state *crtc_state)
{
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);

	trace_intel_disable_plane(&plane->base, crtc);
	plane->disable_plane(plane, crtc_state);
}
예제 #23
0
int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,
			      size_t *values_cnt)
{
	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	enum intel_display_power_domain power_domain;
	enum intel_pipe_crc_source source;
	u32 val = 0; /* shut up gcc */
	int ret = 0;

	if (display_crc_ctl_parse_source(source_name, &source) < 0) {
		DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
		return -EINVAL;
	}

	power_domain = POWER_DOMAIN_PIPE(crtc->index);
	if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
		DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
		return -EIO;
	}

	ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val);
	if (ret != 0)
		goto out;

	if (source) {
		/*
		 * When IPS gets enabled, the pipe CRC changes. Since IPS gets
		 * enabled and disabled dynamically based on package C states,
		 * user space can't make reliable use of the CRCs, so let's just
		 * completely disable it.
		 */
		hsw_disable_ips(intel_crtc);
	}

	I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
	POSTING_READ(PIPE_CRC_CTL(crtc->index));

	if (!source) {
		if (IS_G4X(dev_priv))
			g4x_undo_pipe_scramble_reset(dev_priv, crtc->index);
		else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
			vlv_undo_pipe_scramble_reset(dev_priv, crtc->index);
		else if (IS_HASWELL(dev_priv) && crtc->index == PIPE_A)
			hsw_trans_edp_pipe_A_crc_wa(dev_priv, false);

		hsw_enable_ips(intel_crtc);
	}

	pipe_crc->skipped = 0;
	*values_cnt = 5;

out:
	intel_display_power_put(dev_priv, power_domain);

	return ret;
}
static void set_dsi_timings(struct drm_encoder *encoder,
			    const struct drm_display_mode *mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
	int pipe = intel_crtc->pipe;
	unsigned int bpp = intel_crtc->config.pipe_bpp;
	unsigned int lane_count = intel_dsi->lane_count;

	u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;

	hactive = mode->hdisplay;

	hfp = mode->hsync_start - mode->hdisplay;
	hsync = mode->hsync_end - mode->hsync_start;
	hbp = mode->htotal - mode->hsync_end;

	vfp = mode->vsync_start - mode->vdisplay;
	vsync = mode->vsync_end - mode->vsync_start;
	vbp = mode->vtotal - mode->vsync_end;

	/* horizontal values are in terms of high speed byte clock */
	hactive = txbyteclkhs(hactive, bpp, lane_count);
	hfp = txbyteclkhs(hfp, bpp, lane_count);
	hsync = txbyteclkhs(hsync, bpp, lane_count);
	hbp = txbyteclkhs(hbp, bpp, lane_count);

	/* FIXME: Find better way to do this */
	/* For 7x10 panel we need to have BLLP added to active */
	/* Trying to find optimal BLLP Multiplier */
	/*	2.875 - Original multiplier, Works with flicker */
	/*	2.000 - works but still some flicker */
	/*	1.500 - Works, No Flicker */
	/*	1.250 - Works, No Flicker */
	/*	1.100 - Doesn't work */
	/* FIXME: Acer Mango spec requires to run the DSI clock at 500 to
	 * 560Mbps. Recomendation is to run at 513 Mbps. The addition dsi
	 * clock is to be filled with NULL packets. Refer to acer panel
	 * spec for more details.
	 */
	if (dev_priv->mipi_panel_id == MIPI_DSI_AUO_B080XAT_PANEL_ID)
		hactive = (hactive * 10) / 8;

	I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive);
	I915_WRITE(MIPI_HFP_COUNT(pipe), hfp);

	/* meaningful for video mode non-burst sync pulse mode only, can be zero
	 * for non-burst sync events and burst modes */
	I915_WRITE(MIPI_HSYNC_PADDING_COUNT(pipe), hsync);
	I915_WRITE(MIPI_HBP_COUNT(pipe), hbp);

	/* vertical values are in terms of lines */
	I915_WRITE(MIPI_VFP_COUNT(pipe), vfp);
	I915_WRITE(MIPI_VSYNC_PADDING_COUNT(pipe), vsync);
	I915_WRITE(MIPI_VBP_COUNT(pipe), vbp);
}
예제 #25
0
void intel_update_slave(struct intel_plane *plane,
			const struct intel_crtc_state *crtc_state,
			const struct intel_plane_state *plane_state)
{
	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);

	trace_intel_update_plane(&plane->base, crtc);
	plane->update_slave(plane, crtc_state, plane_state);
}
예제 #26
0
static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector,
							 struct drm_connector_state *state)
{
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct intel_dp *intel_dp = intel_connector->mst_port;
	struct intel_crtc *crtc = to_intel_crtc(state->crtc);

	return &intel_dp->mst_encoders[crtc->pipe]->base.base;
}
예제 #27
0
/** Sets the color ramps on behalf of RandR */
static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
				    u16 blue, int regno)
{
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	intel_crtc->lut_r[regno] = red >> 8;
	intel_crtc->lut_g[regno] = green >> 8;
	intel_crtc->lut_b[regno] = blue >> 8;
}
예제 #28
0
static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
				    u16 *blue, int regno)
{
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	*red = intel_crtc->lut_r[regno] << 8;
	*green = intel_crtc->lut_g[regno] << 8;
	*blue = intel_crtc->lut_b[regno] << 8;
}
int intel_drrs_configure_dsi_pll(struct intel_dsi *intel_dsi,
					struct intel_dsi_mnp *intel_dsi_mnp)
{
	struct drm_i915_private *dev_priv =
			intel_dsi->base.base.dev->dev_private;
	struct intel_crtc *intel_crtc =
				to_intel_crtc(intel_dsi->base.base.crtc);
	struct intel_mipi_drrs_work *work =
				dev_priv->drrs.mipi_drrs_work;
	u32 dsi_pll_ctrl, vactive;
	u32 dsl_offset = PIPEDSL(intel_crtc->pipe), dsl;
	unsigned long timeout;

	intel_configure_dsi_pll_reg(dev_priv, intel_dsi_mnp, intel_dsi, true);

	dsi_pll_ctrl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
	dsi_pll_ctrl &= (~DSI_PLL_VCO_EN);

	vactive = (I915_READ(VTOTAL(intel_crtc->pipe)) &
				VERTICAL_ACTIVE_DISPLAY_MASK) + 1;

	timeout = jiffies + msecs_to_jiffies(50);

	do {
		if (atomic_read(&work->abort_wait_loop) == 1) {
			DRM_DEBUG_KMS("Aborting the pll update\n");
			return -EPERM;
		}

		dsl = (I915_READ(dsl_offset) & DSL_LINEMASK_GEN3);

		if (jiffies >= timeout) {
			DRM_ERROR("Timeout at waiting for Vblank\n");
			return -ETIMEDOUT;
		}
	} while (dsl <= vactive);

	mutex_lock(&dev_priv->dpio_lock);
	/* Toggle the VCO_EN to bring in the new dividers values */
	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl);

	dsi_pll_ctrl |= DSI_PLL_VCO_EN;
	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl);
	mutex_unlock(&dev_priv->dpio_lock);

	DRM_DEBUG_KMS("PLL Changed between DSL: %d, %d\n",
			dsl, I915_READ(dsl_offset) & DSL_LINEMASK_GEN3);

	if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED,
									20)) {
		DRM_ERROR("DSI PLL lock failed\n");
		return -EACCES;
	}

	return 0;
}
void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
{
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
	int pipe = intel_crtc->pipe;
	u32 val;

	DRM_DEBUG_KMS("\n");

	I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER | DEVICE_READY,
							ULPS_STATE_MASK | DEVICE_READY);
	usleep_range(2000, 2500);

	I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT | DEVICE_READY,
							ULPS_STATE_MASK | DEVICE_READY);
	usleep_range(2000, 2500);

	I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER | DEVICE_READY,
							ULPS_STATE_MASK | DEVICE_READY);
	usleep_range(2000, 2500);

	if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & 0x20000)
					== 0x00000), 30))
		DRM_ERROR("DSI LP not going Low\n");

	I915_WRITE_BITS(MIPI_PORT_CTRL(pipe), 0, LP_OUTPUT_HOLD);
	usleep_range(1000, 1500);

	I915_WRITE_BITS(MIPI_DEVICE_READY(pipe), 0x00, DEVICE_READY);
	usleep_range(2000, 2500);

	intel_disable_dsi_pll(intel_dsi);

	val = I915_READ(DSPCLK_GATE_D);
	val &= ~VSUNIT_CLOCK_GATE_DISABLE;
	I915_WRITE(DSPCLK_GATE_D, val);

	if (intel_dsi->dev.dev_ops->disable_panel_power)
		intel_dsi->dev.dev_ops->disable_panel_power(&intel_dsi->dev);

#ifdef CONFIG_CRYSTAL_COVE
	if (BYT_CR_CONFIG) {
		/* Disable Panel */
		vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PCONF0, 0x2000CC00);
		vlv_gpio_nc_write(dev_priv, GPIO_NC_11_PAD, 0x00000004);
		udelay(500);
	} else
		intel_mid_pmic_writeb(PMIC_PANEL_EN, 0x00);
#else
	/* need to code for BYT-CR for example where things have changed */
	DRM_ERROR("PANEL Disable to supported yet\n");
#endif
	msleep(intel_dsi->panel_off_delay);
	msleep(intel_dsi->panel_pwr_cycle_delay);
}