[Intel-gfx] [PATCH] merge mode attributes of VBT and EDID together
Wang, Quanxian
quanxian.wang at intel.com
Wed Jul 1 03:37:56 CEST 2009
Since the mode attributes of EDID is almost the same as VBT,
we merge the implementation together for easy control
Signed-off-by: Wang, Quanxian<quanxian.wang at intel.com<mailto:quanxian.wang at intel.com>>
Signed-off-by: Guo, Changhong<changhong.guo at intel.com<mailto: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__ */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090701/7307653e/attachment.html>
More information about the Intel-gfx
mailing list