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

Commit 2da8af54 authored by Paulo Zanoni's avatar Paulo Zanoni Committed by Daniel Vetter
Browse files

drm/i915: implement hsw_write_infoframe



Both the control and data registers are completely different now.

Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarEugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent ed517fbb
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1697,6 +1697,7 @@
/* Video Data Island Packet control */
#define VIDEO_DIP_DATA		0x61178
#define VIDEO_DIP_CTL		0x61170
/* Pre HSW: */
#define   VIDEO_DIP_ENABLE		(1 << 31)
#define   VIDEO_DIP_PORT_B		(1 << 29)
#define   VIDEO_DIP_PORT_C		(2 << 29)
@@ -1713,6 +1714,9 @@
#define   VIDEO_DIP_FREQ_VSYNC		(1 << 16)
#define   VIDEO_DIP_FREQ_2VSYNC		(2 << 16)
#define   VIDEO_DIP_FREQ_MASK		(3 << 16)
/* HSW and later: */
#define   VIDEO_DIP_ENABLE_AVI_HSW	(1 << 12)
#define   VIDEO_DIP_ENABLE_SPD_HSW	(1 << 0)

/* Panel power sequencing */
#define PP_STATUS	0x61200
+48 −5
Original line number Diff line number Diff line
@@ -89,6 +89,32 @@ static u32 g4x_infoframe_enable(struct dip_infoframe *frame)
	}
}

static u32 hsw_infoframe_enable(struct dip_infoframe *frame)
{
	switch (frame->type) {
	case DIP_TYPE_AVI:
		return VIDEO_DIP_ENABLE_AVI_HSW;
	case DIP_TYPE_SPD:
		return VIDEO_DIP_ENABLE_SPD_HSW;
	default:
		DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
		return 0;
	}
}

static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe pipe)
{
	switch (frame->type) {
	case DIP_TYPE_AVI:
		return HSW_TVIDEO_DIP_AVI_DATA(pipe);
	case DIP_TYPE_SPD:
		return HSW_TVIDEO_DIP_SPD_DATA(pipe);
	default:
		DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type);
		return 0;
	}
}

static void g4x_write_infoframe(struct drm_encoder *encoder,
				struct dip_infoframe *frame)
{
@@ -251,13 +277,30 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
static void hsw_write_infoframe(struct drm_encoder *encoder,
				struct dip_infoframe *frame)
{
	/* Not implemented yet, so avoid doing anything at all.
	 * This is the placeholder for Paulo Zanoni's infoframe writing patch
	 */
	DRM_DEBUG_DRIVER("Attempting to write infoframe on Haswell, this is not implemented yet.\n");
	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;

	intel_wait_for_vblank(dev, intel_crtc->pipe);

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

	for (i = 0; i < len; i += 4) {
		I915_WRITE(data_reg + i, *data);
		data++;
	}

	val |= hsw_infoframe_enable(frame);
	I915_WRITE(ctl_reg, val);
}

static void intel_set_infoframe(struct drm_encoder *encoder,