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

Mike Isely isely at isely.net
Thu Mar 17 14:57:52 CET 2011


LVDS digital data can be formatted as 18 bits/pixel or one of two
24 bits/pixel possibilities.  All are incompatible with one another,
so the GPU's LVDS output has to be configured to match the format
expected by the display device.

In many (most) cases this is generally not a problem because the LVDS
device is integral to the processor board (e.g. a laptop) and thus the
video BIOS already sets this up correctly as part of the boot
process.  Then the i915 drm simply works with what has been already
set up.

But there are cases where the LVDS-driven display and the GPU are
discrete components - this can happen in embedded environments where
the processor board is a COTS device with its own BIOS and the display
is added to it later.  In that situation the video BIOS on the
processor board can't know anything about the LVDS display which leads
to problems if the pixel format is not 18 bit (usually 18 bit is the
default).

This patch implements a new kernel option for the i915 kernel module:
"lvds_24bit".  The default value of zero preserves the previous "don't
change anything" behavior.  If it is set to "1" or "2" then 24 bit
format is enabled - the choice between "1" and "2" selects the
particular 24 bit format.  If it is set to "3" then 24 format is
specifically disabled, which should be an extremely rare case but is
included for completeness.

There was a similar patch back in 2008 to support 24 bit LVDS with the
user-mode xorg intel driver, using a new driver option in the
xorg.conf file.  However that patch was a casualty of the move to
kernel mode switching.  This patch implements the same sort of
solution, just now it's in the kernel drm driver for i915 driven GPUs.

Signed-Off-By: Mike Isely <isely at pobox.com>
---
 drivers/gpu/drm/i915/i915_drv.c      |    4 +++
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/i915_reg.h      |    7 ++++++
 drivers/gpu/drm/i915/intel_display.c |   38 ++++++++++++++++++++++++++++++---
 4 files changed, 46 insertions(+), 4 deletions(-)

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)
-- 
1.5.6.5


-- 

Mike Isely
isely @ isely (dot) net
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8



More information about the Intel-gfx mailing list