All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jesse Barnes <jbarnes@virtuousgeek.org>
To: intel-gfx@lists.freedesktop.org
Subject: [RFC] drm/i915: read current config at init time to avoid flicker
Date: Thu, 1 Mar 2012 12:37:47 -0800	[thread overview]
Message-ID: <20120301123747.1e89da33@jbarnes-desktop> (raw)

The intent here is to build enough of the configuration to allow
set_config to avoid mode setting if possible.

Seems to speed up boot a bit on my Dell E6510; should help other eDP
platforms as well.

One thing that's missing is creating an initial fb for whatever's
display at driver load time.  This would involve poking around in the
display regs to get the offset and making bo and fb objects for the
current framebuffer.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cdcf99b..8f25e68 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7637,6 +7637,66 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
 	.page_flip = intel_crtc_page_flip,
 };
 
+static int intel_crtc_get_bpp(struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipeconf;
+	int ret;
+
+	pipeconf = PIPECONF(intel_crtc->pipe);
+
+	switch (pipeconf & PIPE_BPC_MASK) {
+	case PIPE_6BPC:
+		ret = 18;
+		break;
+	case PIPE_8BPC:
+		ret = 24;
+		break;
+	case PIPE_10BPC:
+		ret = 30;
+		break;
+	case PIPE_12BPC:
+		ret = 36;
+		break;
+	default:
+		ret = 24;
+		break;
+	}
+
+	return ret;
+}
+
+static bool intel_crtc_get_status(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 dspcntr, pipeconf;
+
+	dspcntr = DSPCNTR(intel_crtc->pipe);
+	pipeconf = PIPECONF(intel_crtc->pipe);
+
+	if ((I915_READ(dspcntr) & DISPLAY_PLANE_ENABLE) &&
+	    (I915_READ(pipeconf) & PIPECONF_ENABLE))
+		return true;
+
+	return false;
+}
+
+/*
+ * Get current mode, encoder, and connector info for this CRTC
+ */
+static void intel_crtc_get_config(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_display_mode *mode;
+
+	mode = intel_crtc_mode_get(dev, crtc);
+	crtc->mode = *mode;
+	kfree(mode);
+	crtc->enabled = drm_helper_crtc_in_use(crtc);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7669,9 +7729,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
 	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
 
-	intel_crtc_reset(&intel_crtc->base);
-	intel_crtc->active = true; /* force the pipe off on setup_init_config */
-	intel_crtc->bpp = 24; /* default for pre-Ironlake */
+	intel_crtc->active = intel_crtc_get_status(&intel_crtc->base);
+	intel_crtc->bpp = intel_crtc_get_bpp(&intel_crtc->base);
 
 	if (HAS_PCH_SPLIT(dev)) {
 		if (pipe == 2 && IS_IVYBRIDGE(dev))
@@ -9091,6 +9150,9 @@ static void i915_disable_vga(struct drm_device *dev)
 void intel_modeset_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
 	int i, ret;
 
 	drm_mode_config_init(dev);
@@ -9142,6 +9204,9 @@ void intel_modeset_init(struct drm_device *dev)
 		gen6_update_ring_freq(dev_priv);
 	}
 
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		intel_crtc_get_config(crtc);
+
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 39eccf9..3e24f0b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2360,6 +2360,26 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
 	intel_attach_broadcast_rgb_property(connector);
 }
 
+static struct drm_crtc *intel_dp_get_crtc(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	int pipe;
+
+	pipe = (I915_READ(intel_dp->output_reg) & DP_PIPE_MASK) >> 30;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		intel_crtc = to_intel_crtc(crtc);
+		if (intel_crtc->pipe == pipe)
+			return crtc;
+	}
+
+	return NULL;
+}
+
 void
 intel_dp_init(struct drm_device *dev, int output_reg)
 {
@@ -2419,6 +2439,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
+	connector->encoder = &intel_encoder->base;
 
 	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
@@ -2427,6 +2448,8 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_sysfs_connector_add(connector);
 
+	intel_encoder->base.crtc = intel_dp_get_crtc(&intel_encoder->base);
+
 	/* Set up the DDC bus. */
 	switch (output_reg) {
 		case DP_A:
@@ -2538,4 +2561,6 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
 		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
 	}
+
+	connector->status = intel_dp_detect(connector, 0);
 }

             reply	other threads:[~2012-03-01 20:37 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-01 20:37 Jesse Barnes [this message]
2012-03-01 22:18 ` [RFC] drm/i915: read current config at init time to avoid flicker Jesse Barnes
2012-03-01 22:41   ` Chris Wilson
2012-03-01 22:51     ` Jesse Barnes
2012-03-02  0:08 ` Keith Packard
2012-03-02  0:52   ` Jesse Barnes
2012-03-02  6:30     ` Keith Packard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120301123747.1e89da33@jbarnes-desktop \
    --to=jbarnes@virtuousgeek.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.