diff mbox

[1/3,drm/i915] - Implement direct support for 24 bit LVDS pixel format

Message ID alpine.DEB.1.10.1103161531320.13431@cnc.isely.net (mailing list archive)
State New, archived
Headers show

Commit Message

Mike Isely March 17, 2011, 1:57 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index da769bc12ecd6d63965df571b7cf3e95c474cd46..c89f71c251acf230db613229eca90d24584b9729 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -49,6 +49,10 @@  module_param_named(powersave, i915_powersave, int, 0600);
 unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 
+unsigned int i915_lvds_24bit = 0;
+module_param_named(lvds_24bit, i915_lvds_24bit, int, 0600);
+MODULE_PARM_DESC(lvds_24bit, "LVDS 24 bit pixel format: 0=leave untouched (default), 1=24 bit '2.0' format, 2=24 bit '2.1' format, 3=force older 18 bit format");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d2896ebaba9f81100efc16f1d0cfbe7845d7a997..526cef2972ab9afce1c17f57ef39ce9cc4dc736f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -886,6 +886,7 @@  extern int i915_max_ioctl;
 extern unsigned int i915_fbpercrtc;
 extern unsigned int i915_powersave;
 extern unsigned int i915_lvds_downclock;
+extern unsigned int i915_lvds_24bit;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0a1b276418991f48b81f72f648aa6dc980a618b4..ffe7f459440f10612ac4ab957d4b4eb75205e3ce 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1320,6 +1320,13 @@ 
 #define   LVDS_PIPEB_SELECT		(1 << 30)
 /* LVDS dithering flag on 965/g4x platform */
 #define   LVDS_ENABLE_DITHER		(1 << 25)
+/*
+ * Selects between .0 and .1 formats:
+ *
+ * 0 = 1x18.0, 2x18.0, 1x24.0 or 2x24.0
+ * 1 = 1x24.1 or 2x24.1
+ */
+#define LVDS_DATA_FORMAT_DOT_ONE	(1 << 24)
 /* Enable border for unscaled (or aspect-scaled) display */
 #define   LVDS_BORDER_ENABLE		(1 << 15)
 /*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3abd904ce435a79fb273c0242a18049b55050b9c..09f57f29c30c371c213944be473090a780a287db 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4029,10 +4029,40 @@  static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		else
 			temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
 
-		/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
-		 * appropriately here, but we need to look more thoroughly into how
-		 * panels behave in the two modes.
-		 */
+		/* Control the output pixel format. */
+		switch (i915_lvds_24bit) {
+		default:
+		case 0:
+			/* 0 means don't mess with 18 vs 24 bit LVDS pixel
+			 * format.  Instead we trust whatever the video
+			 * BIOS should have done to set up the panel.
+			 * This is normally the safest choice since most
+			 * LVDS-connected panels are integral to the
+			 * system and thus the video BIOS knows how to set
+			 * it up appropriately. */
+			break;
+		case 1:
+			/* Enable 24 bit pixel mode using the "2.0" format */
+			temp |= LVDS_A3_POWER_UP;
+			temp &= ~LVDS_DATA_FORMAT_DOT_ONE;
+			break;
+		case 2:
+			/* Enable 24 bit pixel mode using the "2.1"
+			 * format; this choice is equivalent to the
+			 * LVDS24BitMode option in the old pre-KMS user
+			 * space driver. */
+			temp |= LVDS_A3_POWER_UP;
+			temp |= LVDS_DATA_FORMAT_DOT_ONE;
+			break;
+		case 3:
+			/* Enable 18 bit pixel mode - this should be a
+			   very rare case since this is usually the
+			   power-up mode if the video BIOS didn't set
+			   things up.  But it's here for completeness. */
+			temp &= ~LVDS_A3_POWER_UP;
+			temp &= ~LVDS_DATA_FORMAT_DOT_ONE;
+			break;
+		}
 		/* set the dithering flag on non-PCH LVDS as needed */
 		if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
 			if (dev_priv->lvds_dither)