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

Commit 045ac3b5 authored by Jesse Barnes's avatar Jesse Barnes Committed by Daniel Vetter
Browse files

drm/i915: add encoder get_config function v5



We can use this for fetching encoder specific pipe_config state, like
mode flags, adjusted clock, etc.

Just used for mode flags atm, so we can check the pipe config state at
mode set time.

v2: get_config when checking hw state too
v3: fix DVO and LVDS mode flags (Ville)
    get SDVO DTD for flag fetch (Ville)
v4: use input timings (Ville)
    correct command used (Ville)
    remove gen4 check (Ville)
v5: get DDI flag config too

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v4)
Tested-by: Paulo Zanoni <przanoni@gmail.com> (the new hsw ddi stuff)
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent e1b73cba
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -84,6 +84,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
	return true;
}

static void intel_crt_get_config(struct intel_encoder *encoder,
				 struct intel_crtc_config *pipe_config)
{
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	struct intel_crt *crt = intel_encoder_to_crt(encoder);
	u32 tmp, flags = 0;

	tmp = I915_READ(crt->adpa_reg);

	if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
		flags |= DRM_MODE_FLAG_PHSYNC;
	else
		flags |= DRM_MODE_FLAG_NHSYNC;

	if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
		flags |= DRM_MODE_FLAG_PVSYNC;
	else
		flags |= DRM_MODE_FLAG_NVSYNC;

	pipe_config->adjusted_mode.flags |= flags;
}

/* Note: The caller is required to filter out dpms modes not supported by the
 * platform. */
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
@@ -778,6 +800,7 @@ void intel_crt_init(struct drm_device *dev)
	crt->base.compute_config = intel_crt_compute_config;
	crt->base.disable = intel_disable_crt;
	crt->base.enable = intel_enable_crt;
	crt->base.get_config = intel_crt_get_config;
	if (I915_HAS_HOTPLUG(dev))
		crt->base.hpd_pin = HPD_CRT;
	if (HAS_DDI(dev))
+23 −0
Original line number Diff line number Diff line
@@ -1259,6 +1259,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
		intel_dp_check_link_status(intel_dp);
}

static void intel_ddi_get_config(struct intel_encoder *encoder,
				 struct intel_crtc_config *pipe_config)
{
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
	u32 temp, flags = 0;

	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
	if (temp & TRANS_DDI_PHSYNC)
		flags |= DRM_MODE_FLAG_PHSYNC;
	else
		flags |= DRM_MODE_FLAG_NHSYNC;
	if (temp & TRANS_DDI_PVSYNC)
		flags |= DRM_MODE_FLAG_PVSYNC;
	else
		flags |= DRM_MODE_FLAG_NVSYNC;

	pipe_config->adjusted_mode.flags |= flags;
	pipe_config->pixel_multiplier = 1;
}

static void intel_ddi_destroy(struct drm_encoder *encoder)
{
	/* HDMI has nothing special to destroy, so we can go with this. */
@@ -1318,6 +1340,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
	intel_encoder->disable = intel_disable_ddi;
	intel_encoder->post_disable = intel_ddi_post_disable;
	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
	intel_encoder->get_config = intel_ddi_get_config;

	intel_dig_port->port = port;
	intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
+17 −3
Original line number Diff line number Diff line
@@ -8067,6 +8067,15 @@ intel_pipe_config_compare(struct drm_device *dev,
	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
			      DRM_MODE_FLAG_INTERLACE);

	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
			      DRM_MODE_FLAG_PHSYNC);
	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
			      DRM_MODE_FLAG_NHSYNC);
	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
			      DRM_MODE_FLAG_PVSYNC);
	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
			      DRM_MODE_FLAG_NVSYNC);

	PIPE_CONF_CHECK_I(requested_mode.hdisplay);
	PIPE_CONF_CHECK_I(requested_mode.vdisplay);

@@ -8159,6 +8168,8 @@ intel_modeset_check_state(struct drm_device *dev)
		bool enabled = false;
		bool active = false;

		memset(&pipe_config, 0, sizeof(pipe_config));

		DRM_DEBUG_KMS("[CRTC:%d]\n",
			      crtc->base.base.id);

@@ -8172,6 +8183,8 @@ intel_modeset_check_state(struct drm_device *dev)
			enabled = true;
			if (encoder->connectors_active)
				active = true;
			if (encoder->get_config)
				encoder->get_config(encoder, &pipe_config);
		}
		WARN(active != crtc->active,
		     "crtc's computed active state doesn't match tracked active state "
@@ -8180,7 +8193,6 @@ intel_modeset_check_state(struct drm_device *dev)
		     "crtc's computed enabled state doesn't match tracked enabled state "
		     "(expected %i, found %i)\n", enabled, crtc->base.enabled);

		memset(&pipe_config, 0, sizeof(pipe_config));
		pipe_config.cpu_transcoder = crtc->config.cpu_transcoder;
		active = dev_priv->display.get_pipe_config(crtc,
							   &pipe_config);
@@ -9589,8 +9601,10 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
		pipe = 0;

		if (encoder->get_hw_state(encoder, &pipe)) {
			encoder->base.crtc =
				dev_priv->pipe_to_crtc_mapping[pipe];
			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
			encoder->base.crtc = &crtc->base;
			if (encoder->get_config)
				encoder->get_config(encoder, &crtc->config);
		} else {
			encoder->base.crtc = NULL;
		}
+23 −0
Original line number Diff line number Diff line
@@ -1346,6 +1346,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
	return true;
}

static void intel_dp_get_config(struct intel_encoder *encoder,
				struct intel_crtc_config *pipe_config)
{
	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
	u32 tmp, flags = 0;

	tmp = I915_READ(intel_dp->output_reg);

	if (tmp & DP_SYNC_HS_HIGH)
		flags |= DRM_MODE_FLAG_PHSYNC;
	else
		flags |= DRM_MODE_FLAG_NHSYNC;

	if (tmp & DP_SYNC_VS_HIGH)
		flags |= DRM_MODE_FLAG_PVSYNC;
	else
		flags |= DRM_MODE_FLAG_NVSYNC;

	pipe_config->adjusted_mode.flags |= flags;
}

static void intel_disable_dp(struct intel_encoder *encoder)
{
	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@ -3184,6 +3206,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
	intel_encoder->disable = intel_disable_dp;
	intel_encoder->post_disable = intel_post_disable_dp;
	intel_encoder->get_hw_state = intel_dp_get_hw_state;
	intel_encoder->get_config = intel_dp_get_config;
	if (IS_VALLEYVIEW(dev))
		intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;

+4 −0
Original line number Diff line number Diff line
@@ -139,6 +139,10 @@ struct intel_encoder {
	 * the encoder is active. If the encoder is enabled it also set the pipe
	 * it is connected to in the pipe parameter. */
	bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
	/* Reconstructs the equivalent mode flags for the current hardware
	 * state. */
	void (*get_config)(struct intel_encoder *,
			   struct intel_crtc_config *pipe_config);
	int crtc_mask;
	enum hpd_pin hpd_pin;
};
Loading