Skip to content

Commit

Permalink
drm/i915: Show bios vbt when read from firmware/spi/oprom
Browse files Browse the repository at this point in the history
Make debugfs vbt only shows valid vbt when read from ACPI opregion.
Make it work when read from firmware/spi/pci oprom cases. In the cases
where VBT needs to be read from spi/pci oprom, take the wakeref to
prevent WARN while reading DE registers during debugfs vbt dump.

v2: Extract getting vbt from different sources to its own function.
    Protect sysfs write with vbt check(Jani)
v3: Fix CI error by probing bios vbt with runtime_pm wakeref
v4: Update commit message and skip waking up runtime while accessing
    vbt from opregion/firmware(Jani)
v5: Skip grabbing unnecessary wakeref(Jani)

Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240304212331.640424-1-radhakrishna.sripada@intel.com
  • Loading branch information
Radhakrishna Sripada authored and Jani Nikula committed Mar 11, 2024
1 parent 0cb9b4e commit a259600
Showing 1 changed file with 33 additions and 29 deletions.
62 changes: 33 additions & 29 deletions drivers/gpu/drm/i915/display/intel_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -3166,6 +3166,32 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915,
return NULL;
}

static const struct vbt_header *intel_bios_get_vbt(struct drm_i915_private *i915,
size_t *sizep)
{
const struct vbt_header *vbt = NULL;
intel_wakeref_t wakeref;

vbt = firmware_get_vbt(i915, sizep);

if (!vbt)
vbt = intel_opregion_get_vbt(i915, sizep);

/*
* If the OpRegion does not have VBT, look in SPI flash
* through MMIO or PCI mapping
*/
if (!vbt && IS_DGFX(i915))
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
vbt = spi_oprom_get_vbt(i915, sizep);

if (!vbt)
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
vbt = oprom_get_vbt(i915, sizep);

return vbt;
}

/**
* intel_bios_init - find VBT and initialize settings from the BIOS
* @i915: i915 device instance
Expand All @@ -3177,7 +3203,6 @@ static struct vbt_header *oprom_get_vbt(struct drm_i915_private *i915,
void intel_bios_init(struct drm_i915_private *i915)
{
const struct vbt_header *vbt;
struct vbt_header *oprom_vbt = NULL;
const struct bdb_header *bdb;

INIT_LIST_HEAD(&i915->display.vbt.display_devices);
Expand All @@ -3191,27 +3216,7 @@ void intel_bios_init(struct drm_i915_private *i915)

init_vbt_defaults(i915);

oprom_vbt = firmware_get_vbt(i915, NULL);
vbt = oprom_vbt;

if (!vbt) {
oprom_vbt = intel_opregion_get_vbt(i915, NULL);
vbt = oprom_vbt;
}

/*
* If the OpRegion does not have VBT, look in SPI flash through MMIO or
* PCI mapping
*/
if (!vbt && IS_DGFX(i915)) {
oprom_vbt = spi_oprom_get_vbt(i915, NULL);
vbt = oprom_vbt;
}

if (!vbt) {
oprom_vbt = oprom_get_vbt(i915, NULL);
vbt = oprom_vbt;
}
vbt = intel_bios_get_vbt(i915, NULL);

if (!vbt)
goto out;
Expand Down Expand Up @@ -3244,7 +3249,7 @@ void intel_bios_init(struct drm_i915_private *i915)
parse_sdvo_device_mapping(i915);
parse_ddi_ports(i915);

kfree(oprom_vbt);
kfree(vbt);
}

static void intel_bios_init_panel(struct drm_i915_private *i915,
Expand Down Expand Up @@ -3774,13 +3779,12 @@ static int intel_bios_vbt_show(struct seq_file *m, void *unused)
const void *vbt;
size_t vbt_size;

/*
* FIXME: VBT might originate from other places than opregion, and then
* this would be incorrect.
*/
vbt = intel_opregion_get_vbt(i915, &vbt_size);
if (vbt)
vbt = intel_bios_get_vbt(i915, &vbt_size);

if (vbt) {
seq_write(m, vbt, vbt_size);
kfree(vbt);
}

return 0;
}
Expand Down

0 comments on commit a259600

Please sign in to comment.