[Intel-gfx] [PATCH 1/2] drm/i915: Fetch mode lines from VBT, then reserve them
Ma, Ling
ling.ma at intel.com
Tue May 12 04:32:26 CEST 2009
>-----Original Message-----
>From: Zhenyu Wang [mailto:zhenyuw at linux.intel.com]
>Sent: Tuesday, May 12, 2009 10:22 AM
>To: Ma, Ling
>Cc: intel-gfx at lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 1/2] drm/i915: Fetch mode
>lines from VBT, then reserve them
>
>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?
>
Yes, but VBT's structure contain detail timing mode list, so we
should fetch all modes available.
>Have you tried this on any SDVO LVDS hw? We might also update
>intel_reg_dumper
>to gather configs on more hw.
No, we haven't this sdvo lvds hw.
Thanks
Ma Ling
>
>> 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
>
More information about the Intel-gfx
mailing list