[Intel-gfx] [PATCH] drm/i915: merge mode attributes of VBT and EDID together

Wang, Quanxian quanxian.wang at intel.com
Thu Jul 2 04:58:11 CEST 2009


Suggested by Jesse, I resend this patch to mailist dri-devel at lists.sourceforget.net and drm owner Dave Airlied.

Jesse wrote:
>Looks much better. Since it touches generic DRM code, you should
>probably send it to Dave and dri-devel at lists.sourceforget.net as well.

Thanks

Regards

Quanxian Wang
===========

Since the mode attributes of EDID is almost the same as VBT,
we merge the implementation together for easy control
Thanks for good idea from Jesse Barness and Guo Chaohong

Signed-off-by: Wang, Quanxian<quanxian.wang at intel.com>
Signed-off-by: Guo, Changhong<changhong.guo at intel.com>
---
 drivers/gpu/drm/drm_edid.c        |   59 +++++++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_bios.c |   49 +++++++------------------------
 include/drm/drm_crtc.h            |    2 +
 3 files changed, 56 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 80cc6d0..2d6be50 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -273,6 +273,47 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
 	return mode;
 }
 
+/*
+ * fill_detail_timing_data - input the mode attributes from EDID and VBT
+ * panel_fixed_mode: the display mode to be set
+ * timing: timing info from VBT or EDID
+ */
+void
+fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+			struct detailed_pixel_timing *timing)
+{
+	unsigned hactive = (timing->hactive_hblank_hi & 0xf0) << 4 | timing->hactive_lo;
+	unsigned vactive = (timing->vactive_vblank_hi & 0xf0) << 4 | timing->vactive_lo;
+	unsigned hblank = (timing->hactive_hblank_hi & 0xf) << 8 | timing->hblank_lo;
+	unsigned vblank = (timing->vactive_vblank_hi & 0xf) << 8 | timing->vblank_lo;
+	unsigned hsync_offset = (timing->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2\ 
+			| timing->hsync_offset_lo;
+	unsigned hsync_pulse_width = (timing->hsync_vsync_offset_pulse_width_hi & 0x30) \
+			<< 4 | timing->hsync_pulse_width_lo;
+	unsigned vsync_offset = (timing->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 |\
+			timing->vsync_offset_pulse_width_lo >> 4;
+	unsigned vsync_pulse_width = (timing->hsync_vsync_offset_pulse_width_hi & 0x3)  \
+			<< 4 | (timing->vsync_offset_pulse_width_lo & 0xf);
+
+	panel_fixed_mode->hdisplay = hactive;
+	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + hsync_offset;
+	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + hsync_pulse_width;
+	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + hblank;
+
+	panel_fixed_mode->vdisplay = vactive;
+	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + vsync_offset;
+	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + vsync_pulse_width;
+	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + vblank;
+
+	drm_mode_set_name(panel_fixed_mode);
+
+	/* Some VBTs have bogus h/vtotal values */
+	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+}
+EXPORT_SYMBOL(fill_detail_timing_data);
 /**
  * drm_mode_detailed - create a new mode from an EDID detailed timing section
  * @dev: DRM device (needed to create new mode)
@@ -292,12 +329,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
 	struct detailed_pixel_timing *pt = &timing->data.pixel_data;
 	unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo;
 	unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo;
-	unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo;
-	unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo;
-	unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo;
-	unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo;
-	unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4;
-	unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf);
 
 	/* ignore tiny modes */
 	if (hactive < 64 || vactive < 64)
@@ -323,17 +354,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
 
 	mode->clock = le16_to_cpu(timing->pixel_clock) * 10;
 
-	mode->hdisplay = hactive;
-	mode->hsync_start = mode->hdisplay + hsync_offset;
-	mode->hsync_end = mode->hsync_start + hsync_pulse_width;
-	mode->htotal = mode->hdisplay + hblank;
-
-	mode->vdisplay = vactive;
-	mode->vsync_start = mode->vdisplay + vsync_offset;
-	mode->vsync_end = mode->vsync_start + vsync_pulse_width;
-	mode->vtotal = mode->vdisplay + vblank;
-
-	drm_mode_set_name(mode);
+	fill_detail_timing_data(mode,pt);
 
 	if (pt->misc & DRM_EDID_PT_INTERLACED)
 		mode->flags |= DRM_MODE_FLAG_INTERLACE;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 716409a..3741d27 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -29,6 +29,7 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "intel_bios.h"
+#include "drm_edid.h"
 
 #define	SLAVE_ADDR1	0x70
 #define	SLAVE_ADDR2	0x72
@@ -59,39 +60,6 @@ find_section(struct bdb_header *bdb, int section_id)
 	return NULL;
 }
 
-static void
-fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
-			struct lvds_dvo_timing *dvo_timing)
-{
-	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
-		dvo_timing->hactive_lo;
-	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
-		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
-	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
-		dvo_timing->hsync_pulse_width;
-	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
-		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
-
-	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
-		dvo_timing->vactive_lo;
-	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
-		dvo_timing->vsync_off;
-	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
-		dvo_timing->vsync_pulse_width;
-	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
-		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
-	panel_fixed_mode->clock = dvo_timing->clock * 10;
-	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
-
-	/* Some VBTs have bogus h/vtotal values */
-	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
-		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
-	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
-		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
-
-	drm_mode_set_name(panel_fixed_mode);
-}
-
 /* Try to find integrated panel data */
 static void
 parse_lfp_panel_data(struct drm_i915_private *dev_priv,
@@ -136,7 +104,12 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
 
 	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
 
-	fill_detail_timing_data(panel_fixed_mode, dvo_timing);
+	if (!panel_fixed_mode)
+		return;
+
+	/* Initialize the reserver to 0 since we don't use them */
+	dvo_timing->rsvd0 = 0;
+	fill_detail_timing_data(panel_fixed_mode, (struct detailed_pixel_timing *)dvo_timing);
 
 	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
@@ -152,7 +125,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
 		      struct bdb_header *bdb)
 {
 	struct bdb_sdvo_lvds_options *sdvo_lvds_options;
-	struct lvds_dvo_timing *dvo_timing;
+	struct lvds_dvo_timing *dvo_timing, *pt;
 	struct drm_display_mode *panel_fixed_mode;
 
 	dev_priv->sdvo_lvds_vbt_mode = NULL;
@@ -170,8 +143,10 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
 	if (!panel_fixed_mode)
 		return;
 
-	fill_detail_timing_data(panel_fixed_mode,
-			dvo_timing + sdvo_lvds_options->panel_type);
+	pt=(dvo_timing + sdvo_lvds_options->panel_type);
+	/* Initialize the reserver to 0 since we don't use them */
+	pt->resvd=0;
+	fill_detail_timing_data(panel_fixed_mode,(struct detailed_pixel_timing *)pt);
 
 	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7300fb8..19e8521 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -736,4 +736,6 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
 extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern bool drm_detect_hdmi_monitor(struct edid *edid);
+extern void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+				     struct detailed_pixel_timing *timing);
 #endif /* __DRM_CRTC_H__ */
 
_______________________________________________
Intel-gfx mailing list
Intel-gfx at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx



More information about the Intel-gfx mailing list