[Intel-gfx] [PATCH 40/43] drm/i915: fetch sync polarity when building initial configuration
Chris Wilson
chris at chris-wilson.co.uk
Fri May 25 14:33:19 CEST 2012
From: Jesse Barnes <jbarnes at virtuousgeek.org>
Read the sync polarity from the output configuration when assigning the
initial mode to the current configuration. This allows a later
set_config call to match the current mode and use a flip instead.
Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_crt.c | 29 +++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_display.c | 28 ++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_dp.c | 26 ++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_drv.h | 2 ++
drivers/gpu/drm/i915/intel_dvo.c | 1 +
drivers/gpu/drm/i915/intel_hdmi.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++
drivers/gpu/drm/i915/intel_sdvo.c | 28 ++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_tv.c | 2 ++
9 files changed, 148 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 75a70c4..f0223d0 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -523,6 +523,33 @@ static void intel_crt_reset(struct drm_connector *connector)
crt->force_hotplug_required = 1;
}
+static u32 intel_crt_mode_flags(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int adpa_reg;
+ u32 val, flags = 0;
+
+ if (HAS_PCH_SPLIT(dev))
+ adpa_reg = PCH_ADPA;
+ else
+ adpa_reg = ADPA;
+
+ val = I915_READ(adpa_reg);
+
+ if (val & ADPA_HSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (val & ADPA_VSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ return flags;
+}
+
/*
* Routines for controlling stuff on the analog port
*/
@@ -641,6 +668,8 @@ void intel_crt_init(struct drm_device *dev)
else
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ crt->base.mode_flags = intel_crt_mode_flags;
+
/*
* Configure the automatic hotplug detection stuff
*/
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6b3ce6d2..874507c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5625,6 +5625,33 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
return clock.dot;
}
+u32 intel_mode_flags_none(struct intel_encoder *intel_encoder)
+{
+ return 0;
+}
+
+/* Get the sync polarity for the mode on this crtc */
+static u32 intel_crtc_mode_flags(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_connector *connector;
+ struct intel_encoder *intel_encoder;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->status != connector_status_connected ||
+ !connector->encoder)
+ continue;
+
+ if (connector->encoder->crtc != crtc)
+ continue;
+
+ intel_encoder = to_intel_encoder(connector->encoder);
+ return intel_encoder->mode_flags(intel_encoder);
+ }
+
+ return 0;
+}
+
/** Returns the currently programmed mode of the given pipe. */
struct drm_display_mode *intel_crtc_mode_get(struct drm_crtc *crtc)
{
@@ -5651,6 +5678,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_crtc *crtc)
mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
mode->vsync_start = (vsync & 0xffff) + 1;
mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
+ mode->flags = intel_crtc_mode_flags(crtc);
drm_mode_set_name(mode);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 924dc27..0885ced 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2336,6 +2336,31 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder)
intel_dp_check_link_status(intel_dp);
}
+static u32
+intel_dp_mode_flags(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp *intel_dp = container_of(intel_encoder,
+ struct intel_dp, base);
+ int reg = intel_dp->output_reg;
+ u32 val, flags = 0;
+
+ val = I915_READ(reg);
+
+ if (val & DP_SYNC_HS_HIGH)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (val & DP_SYNC_VS_HIGH)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ return flags;
+}
+
/* Return which DP Port should be selected for Transcoder DP control */
int
intel_trans_dp_port_sel(struct drm_crtc *crtc)
@@ -2574,6 +2599,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
intel_dp_i2c_init(intel_dp, intel_connector, name);
intel_encoder->hot_plug = intel_dp_hot_plug;
+ intel_encoder->mode_flags = intel_dp_mode_flags;
if (is_edp(intel_dp)) {
dev_priv->int_edp_connector = connector;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1337733..cae7716 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -155,6 +155,7 @@ struct intel_encoder {
int type;
bool needs_tv_clock;
void (*hot_plug)(struct intel_encoder *);
+ u32 (*mode_flags)(struct intel_encoder *);
int crtc_mask;
int clone_mask;
};
@@ -468,6 +469,7 @@ extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
extern void intel_prepare_ddi(struct drm_device *dev);
extern void hsw_fdi_link_train(struct drm_crtc *crtc);
extern void intel_ddi_init(struct drm_device *dev, enum port port);
+extern u32 intel_mode_flags_none(struct intel_encoder *intel_encoder);
/* For use by IVB LP watermark workaround in intel_sprite.c */
extern void intel_update_watermarks(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 8ff2841..7cb05d2 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -363,6 +363,7 @@ void intel_dvo_init(struct drm_device *dev)
intel_encoder = &intel_dvo->base;
drm_encoder_init(dev, &intel_encoder->base,
&intel_dvo_enc_funcs, encoder_type);
+ intel_encoder->mode_flags = intel_mode_flags_none;
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 4c6f141..1e9dfea 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -602,6 +602,29 @@ done:
return 0;
}
+static u32 intel_hdmi_mode_flags(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_hdmi *intel_hdmi = container_of(intel_encoder,
+ struct intel_hdmi, base);
+ u32 val, flags = 0;
+
+ val = I915_READ(intel_hdmi->sdvox_reg);
+
+ if (val & SDVO_HSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (val & SDVO_VSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ return flags;
+}
+
static void intel_hdmi_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
@@ -766,6 +789,8 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
intel_connector_attach_encoder(intel_connector, intel_encoder);
drm_sysfs_connector_add(connector);
+ intel_hdmi->base.mode_flags = intel_hdmi_mode_flags;
+
/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
* 0xd. Failure to do so will result in spurious interrupts being
* generated on the port when a cable is not attached.
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 2a731eb..da3fcf8 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -888,6 +888,11 @@ static bool intel_lvds_supported(struct drm_device *dev)
return IS_MOBILE(dev) && !IS_I830(dev);
}
+static u32 intel_lvds_mode_flags(struct intel_encoder *encoder)
+{
+ return 0;
+}
+
static int intel_lvds_get_pipe(struct intel_lvds *intel_lvds)
{
struct intel_encoder *intel_encoder = &intel_lvds->base;
@@ -1126,6 +1131,8 @@ out:
dev_priv->int_lvds_connector = connector;
drm_sysfs_connector_add(connector);
+ intel_lvds->base.mode_flags = intel_lvds_mode_flags;
+
intel_panel_setup_backlight(dev);
connector->status = intel_lvds_detect(connector, 0);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index a1840f4..ae32c1d 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2474,6 +2474,32 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
return true;
}
+static u32 intel_sdvo_mode_flags(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_sdvo *intel_sdvo = container_of(intel_encoder,
+ struct intel_sdvo, base);
+ u32 val, flags = 0;
+
+ if (INTEL_INFO(dev)->gen < 4)
+ return 0;
+
+ val = I915_READ(intel_sdvo->sdvo_reg);
+
+ if (val & SDVO_HSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+
+ if (val & SDVO_VSYNC_ACTIVE_HIGH)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ return flags;
+}
+
static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
struct i2c_msg *msgs,
int num)
@@ -2593,6 +2619,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
&intel_sdvo->pixel_clock_max))
goto err;
+ intel_sdvo->base.mode_flags = intel_sdvo_mode_flags;
+
DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
"input 1: %c, input 2: %c, "
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 3346612..4435083 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1552,6 +1552,8 @@ intel_tv_init(struct drm_device *dev)
intel_encoder = &intel_tv->base;
connector = &intel_connector->base;
+ intel_encoder->mode_flags = intel_mode_flags_none;
+
/* The documentation, for the older chipsets at least, recommend
* using a polling method rather than hotplug detection for TVs.
* This is because in order to perform the hotplug detection, the PLLs
--
1.7.10
More information about the Intel-gfx
mailing list