[Intel-gfx] [PATCH] drm/i915: only add used connectors to the startup fb

Jesse Barnes jbarnes at virtuousgeek.org
Fri Jul 10 02:34:25 CEST 2009


I noticed while fixing up the FIFO programming code that after a
display blank happened, plane A got enabled on my laptop.  This wastes
a bit of power, but more annoyingly flooded my log with pipe underrun
messages since plane A had never had a proper mode set on it.

This patch prevents unused CRTCs from getting added to the startup fb
config in the first place, so that they don't later get enabled w/o a
valid mode.  It also cleans up the CRTC->fb ownership checking in the
various fb functions.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>

diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 1d30802..6c98fd3 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -52,6 +52,17 @@ struct intelfb_par {
 	uint32_t crtc_ids[2];
 };
 
+static bool crtc_in_fb(struct fb_info *info, struct drm_crtc *crtc)
+{
+	struct intelfb_par *par = info->par;
+	int i;
+
+	for (i = 0; i < par->crtc_count; i++)
+		if (crtc->base.id == par->crtc_ids[i])
+			return true;
+	return false;
+}
+
 static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			unsigned blue, unsigned transp,
 			struct fb_info *info)
@@ -59,21 +70,15 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 	struct intelfb_par *par = info->par;
 	struct drm_device *dev = par->dev;
 	struct drm_crtc *crtc;
-	int i;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 		struct drm_mode_set *modeset = &intel_crtc->mode_set;
 		struct drm_framebuffer *fb = modeset->fb;
 
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		if (i == par->crtc_count)
+		if (!crtc_in_fb(info, crtc))
 			continue;
 
-
 		if (regno > 255)
 			return 1;
 
@@ -201,7 +206,6 @@ static int intelfb_set_par(struct fb_info *info)
 	struct intelfb_par *par = info->par;
 	struct drm_device *dev = par->dev;
 	struct fb_var_screeninfo *var = &info->var;
-	int i;
 
 	DRM_DEBUG("%d %d\n", var->xres, var->pixclock);
 
@@ -216,11 +220,7 @@ static int intelfb_set_par(struct fb_info *info)
 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 			struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-			for (i = 0; i < par->crtc_count; i++)
-				if (crtc->base.id == par->crtc_ids[i])
-					break;
-
-			if (i == par->crtc_count)
+			if (!crtc_in_fb(info, crtc))
 				continue;
 
 			if (crtc->fb == intel_crtc->mode_set.fb) {
@@ -244,14 +244,9 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var,
 	struct drm_crtc *crtc;
 	struct intel_crtc *intel_crtc;
 	int ret = 0;
-	int i;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		if (i == par->crtc_count)
+		if (!crtc_in_fb(info, crtc))
 			continue;
 
 		intel_crtc = to_intel_crtc(crtc);
@@ -280,7 +275,6 @@ static void intelfb_on(struct fb_info *info)
 	struct drm_device *dev = par->dev;
 	struct drm_crtc *crtc;
 	struct drm_encoder *encoder;
-	int i;
 
 	/*
 	 * For each CRTC in this fb, find all associated encoders
@@ -289,9 +283,8 @@ static void intelfb_on(struct fb_info *info)
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
+		if (!crtc_in_fb(info, crtc))
+			continue;
 
 		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
 
@@ -312,7 +305,6 @@ static void intelfb_off(struct fb_info *info, int dpms_mode)
 	struct drm_device *dev = par->dev;
 	struct drm_crtc *crtc;
 	struct drm_encoder *encoder;
-	int i;
 
 	/*
 	 * For each CRTC in this fb, find all associated encoders
@@ -321,9 +313,8 @@ static void intelfb_off(struct fb_info *info, int dpms_mode)
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
+		if (!crtc_in_fb(info, crtc))
+			continue;
 
 		/* Found a CRTC on this fb, now find encoders */
 		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -814,6 +805,9 @@ static int intelfb_single_fb_probe(struct drm_device *dev)
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
+		if (!drm_helper_crtc_in_use(crtc))
+			continue;
+
 		modeset = &intel_crtc->mode_set;
 		modeset->fb = &intel_fb->base;
 		conn_count = 0;



More information about the Intel-gfx mailing list