On Tue, 28 Jul 2015, Deepak M <m.deepak@xxxxxxxxx> wrote: > Currently the field in bdb header which indicates the VBT size > is of 2 bytes, but there are some cases where VBT size exceeds > 64KB in which case this field may not contain the correct VBT size. > So its better to get the VBT size from the mailbox3 if > VBT is not present in the mailbox4 of opregion. > > Signed-off-by: Deepak M <m.deepak@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_drv.h | 5 ++++ > drivers/gpu/drm/i915/intel_bios.c | 43 +++++++++++++++++++-------------- > drivers/gpu/drm/i915/intel_opregion.c | 7 ++++-- > 3 files changed, 35 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 1dbd957..b38f52ee 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1740,6 +1740,11 @@ struct drm_i915_private { > u32 pm_rps_events; > u32 pipestat_irq_mask[I915_MAX_PIPES]; > > + bool vbt_in_mailbox4; > + > + /* value is true when VBT is present in mailbox4 */ > + u32 vbt_size; > + There's already struct intel_opregion opregion field in dev_priv where this belongs instead of cluttering the top level. You should only add vbt size in the struct, and make sure it's valid for all scenarios, mailbox 4 or not, and always check against that. Having size fields with separate validity fields will drive people insane. > struct i915_hotplug hotplug; > struct i915_fbc fbc; > struct i915_drrs drrs; > diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c > index 1b9164e..5e0ff22 100644 > --- a/drivers/gpu/drm/i915/intel_bios.c > +++ b/drivers/gpu/drm/i915/intel_bios.c > @@ -37,17 +37,22 @@ > static int panel_type; > > static const void * > -find_section(const void *_bdb, int section_id) > +find_section(struct drm_i915_private *dev_priv, > + const void *_bdb, int section_id) > { > const struct bdb_header *bdb = _bdb; > const u8 *base = _bdb; > int index = 0; > - u16 total, current_size; > + u32 total, current_size; > u8 current_id; > > /* skip to first section */ > index += bdb->header_size; > - total = bdb->bdb_size; > + > + if (dev_priv->vbt_in_mailbox4) > + total = bdb->bdb_size; > + else > + total = dev_priv->vbt_size; > > /* walk the sections looking for section_id */ > while (index + 3 < total) { > @@ -179,7 +184,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, > struct drm_display_mode *panel_fixed_mode; > int drrs_mode; > > - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); > + lvds_options = find_section(dev_priv, bdb, BDB_LVDS_OPTIONS); > if (!lvds_options) > return; > > @@ -211,11 +216,12 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, > break; > } > > - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); > + lvds_lfp_data = find_section(dev_priv, bdb, BDB_LVDS_LFP_DATA); > if (!lvds_lfp_data) > return; > > - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); > + lvds_lfp_data_ptrs = find_section(dev_priv, bdb, > + BDB_LVDS_LFP_DATA_PTRS); > if (!lvds_lfp_data_ptrs) > return; > > @@ -257,7 +263,7 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, > const struct bdb_lfp_backlight_data *backlight_data; > const struct bdb_lfp_backlight_data_entry *entry; > > - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); > + backlight_data = find_section(dev_priv, bdb, BDB_LVDS_BACKLIGHT); > if (!backlight_data) > return; > > @@ -305,14 +311,15 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv, > if (index == -1) { > const struct bdb_sdvo_lvds_options *sdvo_lvds_options; > > - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); > + sdvo_lvds_options = find_section(dev_priv, bdb, > + BDB_SDVO_LVDS_OPTIONS); > if (!sdvo_lvds_options) > return; > > index = sdvo_lvds_options->panel_type; > } > > - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); > + dvo_timing = find_section(dev_priv, bdb, BDB_SDVO_PANEL_DTDS); > if (!dvo_timing) > return; > > @@ -349,7 +356,7 @@ parse_general_features(struct drm_i915_private *dev_priv, > struct drm_device *dev = dev_priv->dev; > const struct bdb_general_features *general; > > - general = find_section(bdb, BDB_GENERAL_FEATURES); > + general = find_section(dev_priv, bdb, BDB_GENERAL_FEATURES); > if (general) { > dev_priv->vbt.int_tv_support = general->int_tv_support; > dev_priv->vbt.int_crt_support = general->int_crt_support; > @@ -374,7 +381,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv, > { > const struct bdb_general_definitions *general; > > - general = find_section(bdb, BDB_GENERAL_DEFINITIONS); > + general = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS); > if (general) { > u16 block_size = get_blocksize(general); > if (block_size >= sizeof(*general)) { > @@ -405,7 +412,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, > int i, child_device_num, count; > u16 block_size; > > - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); > + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS); > if (!p_defs) { > DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); > return; > @@ -491,7 +498,7 @@ parse_driver_features(struct drm_i915_private *dev_priv, > { > const struct bdb_driver_features *driver; > > - driver = find_section(bdb, BDB_DRIVER_FEATURES); > + driver = find_section(dev_priv, bdb, BDB_DRIVER_FEATURES); > if (!driver) > return; > > @@ -519,7 +526,7 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) > const struct edp_power_seq *edp_pps; > const struct edp_link_params *edp_link_params; > > - edp = find_section(bdb, BDB_EDP); > + edp = find_section(dev_priv, bdb, BDB_EDP); > if (!edp) { > if (dev_priv->vbt.edp_support) > DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); > @@ -630,7 +637,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) > const struct bdb_psr *psr; > const struct psr_table *psr_table; > > - psr = find_section(bdb, BDB_PSR); > + psr = find_section(dev_priv, bdb, BDB_PSR); > if (!psr) { > DRM_DEBUG_KMS("No PSR BDB found.\n"); > return; > @@ -768,7 +775,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) > /* Parse #52 for panel index used from panel_type already > * parsed > */ > - start = find_section(bdb, BDB_MIPI_CONFIG); > + start = find_section(dev_priv, bdb, BDB_MIPI_CONFIG); > if (!start) { > DRM_DEBUG_KMS("No MIPI config BDB found"); > return; > @@ -799,7 +806,7 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) > dev_priv->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; > > /* Check if we have sequence block as well */ > - sequence = find_section(bdb, BDB_MIPI_SEQUENCE); > + sequence = find_section(dev_priv, bdb, BDB_MIPI_SEQUENCE); > if (!sequence) { > DRM_DEBUG_KMS("No MIPI Sequence found, parsing complete\n"); > return; > @@ -1023,7 +1030,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, > int i, child_device_num, count; > u16 block_size; > > - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); > + p_defs = find_section(dev_priv, bdb, BDB_GENERAL_DEFINITIONS); > if (!p_defs) { > DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); > return; > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > index 1372e39..1f76715 100644 > --- a/drivers/gpu/drm/i915/intel_opregion.c > +++ b/drivers/gpu/drm/i915/intel_opregion.c > @@ -896,11 +896,14 @@ int intel_opregion_setup(struct drm_device *dev) > opregion->header = base; > opregion->asle = base + OPREGION_ASLE_OFFSET; > > + dev_priv->vbt_in_mailbox4 = true; > if (opregion->header->opregion_ver >= 2) { > - if (opregion->asle->rvda) > + if (opregion->asle->rvda) { > vbt_base = acpi_os_ioremap(opregion->asle->rvda, > opregion->asle->rvds); > - else > + dev_priv->vbt_in_mailbox4 = false; > + dev_priv->vbt_size = opregion->asle->rvds; > + } else > vbt_base = acpi_os_ioremap(asls + OPREGION_VBT_OFFSET, > OPREGION_SIZE - OPREGION_VBT_OFFSET); > } else > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx