summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c149
1 files changed, 28 insertions, 121 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index c57426940cf8..9967b65e3cf6 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -33,12 +33,12 @@
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
+#include "soc/intel_rom.h"
+
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_gmbus.h"
-#include "intel_uncore.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@@ -3056,152 +3056,59 @@ static struct vbt_header *firmware_get_vbt(struct intel_display *display,
return vbt;
}
-static u32 intel_spi_read32(struct intel_uncore *uncore, u32 offset)
-{
- intel_uncore_write(uncore, PRIMARY_SPI_ADDRESS, offset);
-
- return intel_uncore_read(uncore, PRIMARY_SPI_TRIGGER);
-}
-
-static u16 intel_spi_read16(struct intel_uncore *uncore, u32 offset)
-{
- return intel_spi_read32(uncore, offset) & 0xffff;
-}
-
-static struct vbt_header *spi_oprom_get_vbt(struct intel_display *display,
- size_t *size)
+static struct vbt_header *oprom_get_vbt(struct intel_display *display,
+ struct intel_rom *rom,
+ size_t *size, const char *type)
{
- struct drm_i915_private *i915 = to_i915(display->drm);
- u32 count, data, found, store = 0;
- u32 static_region, oprom_offset;
- u32 oprom_size = 0x200000;
- u16 vbt_size;
- u32 *vbt;
-
- static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS);
- static_region &= OPTIONROM_SPI_REGIONID_MASK;
- intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region);
+ struct vbt_header *vbt;
+ size_t vbt_size;
+ loff_t offset;
- oprom_offset = intel_uncore_read(&i915->uncore, OROM_OFFSET);
- oprom_offset &= OROM_OFFSET_MASK;
+ if (!rom)
+ return NULL;
BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1);
BUILD_BUG_ON(vbt_signature_len != sizeof(u32));
- for (count = 0; count < oprom_size; count += 4) {
- data = intel_spi_read32(&i915->uncore, oprom_offset + count);
- if (data == *((const u32 *)vbt_signature)) {
- found = oprom_offset + count;
- break;
- }
- }
+ offset = intel_rom_find(rom, *(const u32 *)vbt_signature);
+ if (offset < 0)
+ goto err_free_rom;
- if (count >= oprom_size)
- goto err_not_found;
-
- if (sizeof(struct vbt_header) > oprom_size - count) {
+ if (sizeof(struct vbt_header) > intel_rom_size(rom) - offset) {
drm_dbg_kms(display->drm, "VBT header incomplete\n");
- goto err_not_found;
+ goto err_free_rom;
}
- /* Get VBT size and allocate space for the VBT */
- vbt_size = intel_spi_read16(&i915->uncore,
- found + offsetof(struct vbt_header, vbt_size));
+ BUILD_BUG_ON(sizeof(vbt->vbt_size) != sizeof(u16));
- if (vbt_size > oprom_size - count) {
- drm_dbg_kms(display->drm,
- "VBT incomplete (vbt_size overflows)\n");
- goto err_not_found;
+ vbt_size = intel_rom_read16(rom, offset + offsetof(struct vbt_header, vbt_size));
+ if (vbt_size > intel_rom_size(rom) - offset) {
+ drm_dbg_kms(display->drm, "VBT incomplete (vbt_size overflows)\n");
+ goto err_free_rom;
}
vbt = kzalloc(round_up(vbt_size, 4), GFP_KERNEL);
if (!vbt)
- goto err_not_found;
+ goto err_free_rom;
- for (count = 0; count < vbt_size; count += 4)
- *(vbt + store++) = intel_spi_read32(&i915->uncore, found + count);
+ intel_rom_read_block(rom, vbt, offset, vbt_size);
if (!intel_bios_is_valid_vbt(display, vbt, vbt_size))
goto err_free_vbt;
- drm_dbg_kms(display->drm, "Found valid VBT in SPI flash\n");
+ drm_dbg_kms(display->drm, "Found valid VBT in %s\n", type);
if (size)
*size = vbt_size;
- return (struct vbt_header *)vbt;
-
-err_free_vbt:
- kfree(vbt);
-err_not_found:
- return NULL;
-}
-
-static struct vbt_header *oprom_get_vbt(struct intel_display *display,
- size_t *sizep)
-{
- struct pci_dev *pdev = to_pci_dev(display->drm->dev);
- void __iomem *p = NULL, *oprom;
- struct vbt_header *vbt;
- u16 vbt_size;
- size_t i, size;
-
- oprom = pci_map_rom(pdev, &size);
- if (!oprom)
- return NULL;
-
- BUILD_BUG_ON(vbt_signature_len != sizeof(vbt_signature) - 1);
- BUILD_BUG_ON(vbt_signature_len != sizeof(u32));
-
- /* Scour memory looking for the VBT signature. */
- for (i = 0; i + 4 < size; i += 4) {
- if (ioread32(oprom + i) != *((const u32 *)vbt_signature))
- continue;
-
- p = oprom + i;
- size -= i;
- break;
- }
-
- if (!p)
- goto err_unmap_oprom;
-
- if (sizeof(struct vbt_header) > size) {
- drm_dbg_kms(display->drm, "VBT header incomplete\n");
- goto err_unmap_oprom;
- }
-
- vbt_size = ioread16(p + offsetof(struct vbt_header, vbt_size));
- if (vbt_size > size) {
- drm_dbg_kms(display->drm,
- "VBT incomplete (vbt_size overflows)\n");
- goto err_unmap_oprom;
- }
-
- /* The rest will be validated by intel_bios_is_valid_vbt() */
- vbt = kmalloc(round_up(vbt_size, 4), GFP_KERNEL);
- if (!vbt)
- goto err_unmap_oprom;
-
- memcpy_fromio(vbt, p, vbt_size);
-
- if (!intel_bios_is_valid_vbt(display, vbt, vbt_size))
- goto err_free_vbt;
-
- pci_unmap_rom(pdev, oprom);
-
- if (sizep)
- *sizep = vbt_size;
-
- drm_dbg_kms(display->drm, "Found valid VBT in PCI ROM\n");
+ intel_rom_free(rom);
return vbt;
err_free_vbt:
kfree(vbt);
-err_unmap_oprom:
- pci_unmap_rom(pdev, oprom);
-
+err_free_rom:
+ intel_rom_free(rom);
return NULL;
}
@@ -3223,11 +3130,11 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display
*/
if (!vbt && IS_DGFX(i915))
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
- vbt = spi_oprom_get_vbt(display, sizep);
+ vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash");
if (!vbt)
with_intel_runtime_pm(&i915->runtime_pm, wakeref)
- vbt = oprom_get_vbt(display, sizep);
+ vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM");
return vbt;
}