[Intel-gfx] [PATCH] drm/i915: merge mode attributes of VBT and EDID together
Dave Airlie
airlied at gmail.com
Wed Jul 15 08:43:20 CEST 2009
On Thu, Jul 2, 2009 at 12:58 PM, Wang, Quanxian<quanxian.wang at intel.com> wrote:
>
> Suggested by Jesse, I resend this patch to mailist dri-devel at lists.sourceforget.net and drm owner Dave Airlied.
>
sorry got sidetracked.
> 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);
Can we change the name away from panel_fixed_mode? since it certainly
isn't that anymore.
Otherwise it looks fine. I'll add it to drm-next if you can clean up the naming.
Dave.
> /**
> * 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
> _______________________________________________
> 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