<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.5764" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT size=2>Since the mode attributes of EDID is almost the same as 
VBT,<BR>we merge the implementation together for easy control<BR></FONT></DIV>
<DIV><FONT size=2>Signed-off-by: Wang, Quanxian<<A 
href="mailto:quanxian.wang@intel.com">quanxian.wang@intel.com</A>><BR>Signed-off-by: 
Guo, Changhong<<A 
href="mailto:changhong.guo@intel.com">changhong.guo@intel.com</A>><BR>---<BR> drivers/gpu/drm/drm_edid.c        
|   59 
+++++++++++++++++++++++++++-----------<BR> drivers/gpu/drm/i915/intel_bios.c 
|   49 
+++++++------------------------<BR> include/drm/drm_crtc.h            
|    2 +<BR> 3 files changed, 56 insertions(+), 54 
deletions(-)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=2>diff --git a/drivers/gpu/drm/drm_edid.c 
b/drivers/gpu/drm/drm_edid.c<BR>index 80cc6d0..2d6be50 100644<BR>--- 
a/drivers/gpu/drm/drm_edid.c<BR>+++ b/drivers/gpu/drm/drm_edid.c<BR>@@ -273,6 
+273,47 @@ struct drm_display_mode *drm_mode_std(struct drm_device 
*dev,<BR>  return mode;<BR> }<BR> <BR>+/*<BR>+ * 
fill_detail_timing_data - input the mode attributes from EDID and VBT<BR>+ * 
panel_fixed_mode: the display mode to be set<BR>+ * timing: timing info from VBT 
or EDID<BR>+ */<BR>+void<BR>+fill_detail_timing_data(struct drm_display_mode 
*panel_fixed_mode,<BR>+   struct detailed_pixel_timing 
*timing)<BR>+{<BR>+ unsigned hactive = (timing->hactive_hblank_hi & 
0xf0) << 4 | timing->hactive_lo;<BR>+ unsigned vactive = 
(timing->vactive_vblank_hi & 0xf0) << 4 | 
timing->vactive_lo;<BR>+ unsigned hblank = (timing->hactive_hblank_hi 
& 0xf) << 8 | timing->hblank_lo;<BR>+ unsigned vblank = 
(timing->vactive_vblank_hi & 0xf) << 8 | 
timing->vblank_lo;<BR>+ unsigned hsync_offset = 
(timing->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2\ 
<BR>+   | timing->hsync_offset_lo;<BR>+ unsigned 
hsync_pulse_width = (timing->hsync_vsync_offset_pulse_width_hi & 0x30) 
\<BR>+   << 4 | 
timing->hsync_pulse_width_lo;<BR>+ unsigned vsync_offset = 
(timing->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 
|\<BR>+   timing->vsync_offset_pulse_width_lo >> 
4;<BR>+ unsigned vsync_pulse_width = 
(timing->hsync_vsync_offset_pulse_width_hi & 0x3)  
\<BR>+   << 4 | (timing->vsync_offset_pulse_width_lo 
& 0xf);<BR>+<BR>+ panel_fixed_mode->hdisplay = 
hactive;<BR>+ panel_fixed_mode->hsync_start = 
panel_fixed_mode->hdisplay + 
hsync_offset;<BR>+ panel_fixed_mode->hsync_end = 
panel_fixed_mode->hsync_start + 
hsync_pulse_width;<BR>+ panel_fixed_mode->htotal = 
panel_fixed_mode->hdisplay + 
hblank;<BR>+<BR>+ panel_fixed_mode->vdisplay = 
vactive;<BR>+ panel_fixed_mode->vsync_start = 
panel_fixed_mode->vdisplay + 
vsync_offset;<BR>+ panel_fixed_mode->vsync_end = 
panel_fixed_mode->vsync_start + 
vsync_pulse_width;<BR>+ panel_fixed_mode->vtotal = 
panel_fixed_mode->vdisplay + 
vblank;<BR>+<BR>+ drm_mode_set_name(panel_fixed_mode);<BR>+<BR>+ /* 
Some VBTs have bogus h/vtotal values */<BR>+ if 
(panel_fixed_mode->hsync_end > 
panel_fixed_mode->htotal)<BR>+  panel_fixed_mode->htotal = 
panel_fixed_mode->hsync_end + 1;<BR>+ if (panel_fixed_mode->vsync_end 
> panel_fixed_mode->vtotal)<BR>+  panel_fixed_mode->vtotal = 
panel_fixed_mode->vsync_end + 
1;<BR>+}<BR>+EXPORT_SYMBOL(fill_detail_timing_data);<BR> /**<BR>  * 
drm_mode_detailed - create a new mode from an EDID detailed timing 
section<BR>  * @dev: DRM device (needed to create new mode)<BR>@@ -292,12 
+329,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device 
*dev,<BR>  struct detailed_pixel_timing *pt = 
&timing->data.pixel_data;<BR>  unsigned hactive = 
(pt->hactive_hblank_hi & 0xf0) << 4 | 
pt->hactive_lo;<BR>  unsigned vactive = (pt->vactive_vblank_hi 
& 0xf0) << 4 | pt->vactive_lo;<BR>- unsigned hblank = 
(pt->hactive_hblank_hi & 0xf) << 8 | 
pt->hblank_lo;<BR>- unsigned vblank = (pt->vactive_vblank_hi & 
0xf) << 8 | pt->vblank_lo;<BR>- unsigned hsync_offset = 
(pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | 
pt->hsync_offset_lo;<BR>- unsigned hsync_pulse_width = 
(pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | 
pt->hsync_pulse_width_lo;<BR>- unsigned vsync_offset = 
(pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | 
pt->vsync_offset_pulse_width_lo >> 4;<BR>- unsigned 
vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) 
<< 4 | (pt->vsync_offset_pulse_width_lo & 
0xf);<BR> <BR>  /* ignore tiny modes */<BR>  if 
(hactive < 64 || vactive < 64)<BR>@@ -323,17 +354,7 @@ static struct 
drm_display_mode *drm_mode_detailed(struct drm_device 
*dev,<BR> <BR>  mode->clock = 
le16_to_cpu(timing->pixel_clock) * 10;<BR> <BR>- mode->hdisplay 
= hactive;<BR>- mode->hsync_start = mode->hdisplay + 
hsync_offset;<BR>- mode->hsync_end = mode->hsync_start + 
hsync_pulse_width;<BR>- mode->htotal = mode->hdisplay + 
hblank;<BR>-<BR>- mode->vdisplay = 
vactive;<BR>- mode->vsync_start = mode->vdisplay + 
vsync_offset;<BR>- mode->vsync_end = mode->vsync_start + 
vsync_pulse_width;<BR>- mode->vtotal = mode->vdisplay + 
vblank;<BR>-<BR>- drm_mode_set_name(mode);<BR>+ fill_detail_timing_data(mode,pt);<BR> <BR>  if 
(pt->misc & DRM_EDID_PT_INTERLACED)<BR>   mode->flags 
|= DRM_MODE_FLAG_INTERLACE;<BR>diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c<BR>index 716409a..3741d27 100644<BR>--- 
a/drivers/gpu/drm/i915/intel_bios.c<BR>+++ 
b/drivers/gpu/drm/i915/intel_bios.c<BR>@@ -29,6 +29,7 @@<BR> #include 
"i915_drm.h"<BR> #include "i915_drv.h"<BR> #include 
"intel_bios.h"<BR>+#include 
"drm_edid.h"<BR> <BR> #define SLAVE_ADDR1 0x70<BR> #define SLAVE_ADDR2 0x72<BR>@@ 
-59,39 +60,6 @@ find_section(struct bdb_header *bdb, int 
section_id)<BR>  return NULL;<BR> }<BR> <BR>-static 
void<BR>-fill_detail_timing_data(struct drm_display_mode 
*panel_fixed_mode,<BR>-   struct lvds_dvo_timing 
*dvo_timing)<BR>-{<BR>- panel_fixed_mode->hdisplay = 
(dvo_timing->hactive_hi << 8) 
|<BR>-  dvo_timing->hactive_lo;<BR>- panel_fixed_mode->hsync_start 
= panel_fixed_mode->hdisplay +<BR>-  ((dvo_timing->hsync_off_hi 
<< 8) | 
dvo_timing->hsync_off_lo);<BR>- panel_fixed_mode->hsync_end = 
panel_fixed_mode->hsync_start 
+<BR>-  dvo_timing->hsync_pulse_width;<BR>- panel_fixed_mode->htotal 
= panel_fixed_mode->hdisplay +<BR>-  ((dvo_timing->hblank_hi 
<< 8) | 
dvo_timing->hblank_lo);<BR>-<BR>- panel_fixed_mode->vdisplay = 
(dvo_timing->vactive_hi << 8) 
|<BR>-  dvo_timing->vactive_lo;<BR>- panel_fixed_mode->vsync_start 
= panel_fixed_mode->vdisplay 
+<BR>-  dvo_timing->vsync_off;<BR>- panel_fixed_mode->vsync_end 
= panel_fixed_mode->vsync_start 
+<BR>-  dvo_timing->vsync_pulse_width;<BR>- panel_fixed_mode->vtotal 
= panel_fixed_mode->vdisplay +<BR>-  ((dvo_timing->vblank_hi 
<< 8) | dvo_timing->vblank_lo);<BR>- panel_fixed_mode->clock = 
dvo_timing->clock * 10;<BR>- panel_fixed_mode->type = 
DRM_MODE_TYPE_PREFERRED;<BR>-<BR>- /* Some VBTs have bogus h/vtotal values 
*/<BR>- if (panel_fixed_mode->hsync_end > 
panel_fixed_mode->htotal)<BR>-  panel_fixed_mode->htotal = 
panel_fixed_mode->hsync_end + 1;<BR>- if (panel_fixed_mode->vsync_end 
> panel_fixed_mode->vtotal)<BR>-  panel_fixed_mode->vtotal = 
panel_fixed_mode->vsync_end + 
1;<BR>-<BR>- drm_mode_set_name(panel_fixed_mode);<BR>-}<BR>-<BR> /* 
Try to find integrated panel data */<BR> static 
void<BR> parse_lfp_panel_data(struct drm_i915_private *dev_priv,<BR>@@ 
-136,7 +104,12 @@ parse_lfp_panel_data(struct drm_i915_private 
*dev_priv,<BR> <BR>  panel_fixed_mode = 
kzalloc(sizeof(*panel_fixed_mode), 
GFP_KERNEL);<BR> <BR>- fill_detail_timing_data(panel_fixed_mode, 
dvo_timing);<BR>+ if 
(!panel_fixed_mode)<BR>+  return;<BR>+<BR>+ /* Initialize the 
reserver to 0 since we don't use them */<BR>+ dvo_timing->rsvd0 = 
0;<BR>+ fill_detail_timing_data(panel_fixed_mode, (struct 
detailed_pixel_timing 
*)dvo_timing);<BR> <BR>  dev_priv->lfp_lvds_vbt_mode = 
panel_fixed_mode;<BR> <BR>@@ -152,7 +125,7 @@ parse_sdvo_panel_data(struct 
drm_i915_private *dev_priv,<BR>         
struct bdb_header *bdb)<BR> {<BR>  struct bdb_sdvo_lvds_options 
*sdvo_lvds_options;<BR>- struct lvds_dvo_timing 
*dvo_timing;<BR>+ struct lvds_dvo_timing *dvo_timing, 
*pt;<BR>  struct drm_display_mode 
*panel_fixed_mode;<BR> <BR>  dev_priv->sdvo_lvds_vbt_mode = 
NULL;<BR>@@ -170,8 +143,10 @@ parse_sdvo_panel_data(struct drm_i915_private 
*dev_priv,<BR>  if 
(!panel_fixed_mode)<BR>   return;<BR> <BR>- fill_detail_timing_data(panel_fixed_mode,<BR>-   dvo_timing 
+ sdvo_lvds_options->panel_type);<BR>+ pt=(dvo_timing + 
sdvo_lvds_options->panel_type);<BR>+ /* Initialize the reserver to 0 
since we don't use them 
*/<BR>+ pt->resvd=0;<BR>+ fill_detail_timing_data(panel_fixed_mode,(struct 
detailed_pixel_timing 
*)pt);<BR> <BR>  dev_priv->sdvo_lvds_vbt_mode = 
panel_fixed_mode;<BR> <BR>diff --git a/include/drm/drm_crtc.h 
b/include/drm/drm_crtc.h<BR>index 7300fb8..19e8521 100644<BR>--- 
a/include/drm/drm_crtc.h<BR>+++ b/include/drm/drm_crtc.h<BR>@@ -736,4 +736,6 @@ 
extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,<BR> extern int 
drm_mode_gamma_set_ioctl(struct drm_device 
*dev,<BR>         void *data, struct 
drm_file *file_priv);<BR> extern bool drm_detect_hdmi_monitor(struct edid 
*edid);<BR>+extern void fill_detail_timing_data(struct drm_display_mode 
*panel_fixed_mode,<BR>+         struct 
detailed_pixel_timing *timing);<BR> #endif /* __DRM_CRTC_H__ 
*/<BR></FONT></DIV></BODY></HTML>