[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