[Intel-gfx] [PATCH 1/2] drm/i915: Fetch mode lines from VBT, then reserve them
Zhenyu Wang
zhenyuw at linux.intel.com
Tue May 12 04:22:18 CEST 2009
On 2009.05.08 18:38:16 +0800, Ma Ling wrote:
> Intends to fetch mode lines in VBT
>
> Signed-off-by: Ma Ling <ling.ma at intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/intel_bios.c | 113 +++++++++++++++++++++++++++----------
> 2 files changed, 84 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 2506592..ef156e3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -181,6 +181,7 @@ typedef struct drm_i915_private {
> bool panel_wants_dither;
> struct drm_display_mode *panel_fixed_mode;
> struct drm_display_mode *vbt_mode; /* if any */
> + struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
>
> /* Feature bits from the VBIOS */
> unsigned int int_tv_support:1;
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index fc28e2b..2be2627 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -57,9 +57,43 @@ find_section(struct bdb_header *bdb, int section_id)
> return NULL;
> }
>
> -/* Try to find panel data */
> static void
> -parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
> +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_integrated_panel_data(struct drm_i915_private *dev_priv,
> + struct bdb_header *bdb)
> {
> struct bdb_lvds_options *lvds_options;
> struct bdb_lvds_lfp_data *lvds_lfp_data;
> @@ -91,33 +125,7 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
> panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
> DRM_MEM_DRIVER);
>
> - 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);
> + fill_detail_timing_data(panel_fixed_mode, dvo_timing);
>
> dev_priv->vbt_mode = panel_fixed_mode;
>
> @@ -127,6 +135,50 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
> return;
> }
>
> +/* Try to find sdvo panel data */
> +static void
> +parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
> + struct bdb_header *bdb)
> +{
> + struct lvds_dvo_timing *dvo_timing, *dvo_timing_end;
> + struct drm_display_mode *panel_fixed_mode;
> + char *parse;
> + uint16_t dvo_size, dvo_num;
> +
> + dev_priv->sdvo_lvds_vbt_mode = NULL;
> +
> + dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
> + if (dvo_timing == NULL)
> + return;
> +
> + parse = ((char *)dvo_timing) - 2;
> +
> + dvo_size = parse[0] | (parse[1] << 8);
> + dvo_num = dvo_size / sizeof(struct lvds_dvo_timing);
> + if (dvo_size == 0 || dvo_num == 0)
> + return;
> +
> + dvo_timing_end = dvo_timing + dvo_num;
> +
> + for (; dvo_timing < dvo_timing_end; dvo_timing = dvo_timing + 1) {
> + panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
> + DRM_MEM_DRIVER);
> + if (panel_fixed_mode == NULL)
> + break;
> +
> + fill_detail_timing_data(panel_fixed_mode, dvo_timing);
> +
> + if (dev_priv->sdvo_lvds_vbt_mode == NULL) {
> + dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
> + INIT_LIST_HEAD(&dev_priv->sdvo_lvds_vbt_mode->head);
> + } else
> + list_add(&panel_fixed_mode->head,
> + &dev_priv->sdvo_lvds_vbt_mode->head);
> + }
> +
> + return;
> +}
> +
Why does this parse all modes? Usually there should be one 'current' panel
mode identified in VBT, so just getting that mode out is enough for panel
fixed mode, no?
Have you tried this on any SDVO LVDS hw? We might also update intel_reg_dumper
to gather configs on more hw.
> static void
> parse_general_features(struct drm_i915_private *dev_priv,
> struct bdb_header *bdb)
> @@ -199,7 +251,8 @@ intel_init_bios(struct drm_device *dev)
>
> /* Grab useful general definitions */
> parse_general_features(dev_priv, bdb);
> - parse_panel_data(dev_priv, bdb);
> + parse_integrated_panel_data(dev_priv, bdb);
> + parse_sdvo_panel_data(dev_priv, bdb);
>
> pci_unmap_rom(pdev, bios);
>
> --
> 1.5.4.4
>
>
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090512/af4f3928/attachment.sig>
More information about the Intel-gfx
mailing list