File Index
Files and directories
Sign in
FILE

intel_rom.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/soc/intel_rom.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2024 Intel Corporation
  4 */
  5
  6#include "i915_drv.h"
  7#include "i915_reg.h"
  8
  9#include "intel_rom.h"
 10#include "intel_uncore.h"
 11
 12struct intel_rom {
 13	/* for PCI ROM */
 14	struct pci_dev *pdev;
 15	void __iomem *oprom;
 16
 17	/* for SPI */
 18	struct intel_uncore *uncore;
 19	loff_t offset;
 20
 21	size_t size;
 22
 23	u32 (*read32)(struct intel_rom *rom, loff_t offset);
 24	u16 (*read16)(struct intel_rom *rom, loff_t offset);
 25	void (*read_block)(struct intel_rom *rom, void *data, loff_t offset, size_t size);
 26	void (*free)(struct intel_rom *rom);
 27};
 28
 29static u32 spi_read32(struct intel_rom *rom, loff_t offset)
 30{
 31	intel_uncore_write(rom->uncore, PRIMARY_SPI_ADDRESS,
 32			   rom->offset + offset);
 33
 34	return intel_uncore_read(rom->uncore, PRIMARY_SPI_TRIGGER);
 35}
 36
 37static u16 spi_read16(struct intel_rom *rom, loff_t offset)
 38{
 39	return spi_read32(rom, offset) & 0xffff;
 40}
 41
 42struct intel_rom *intel_rom_spi(struct drm_device *drm)
 43{
 44	struct drm_i915_private *i915 = to_i915(drm);
 45	struct intel_rom *rom;
 46	u32 static_region;
 47
 48	rom = kzalloc(sizeof(*rom), GFP_KERNEL);
 49	if (!rom)
 50		return NULL;
 51
 52	rom->uncore = &i915->uncore;
 53
 54	static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS);
 55	static_region &= OPTIONROM_SPI_REGIONID_MASK;
 56	intel_uncore_write(rom->uncore, PRIMARY_SPI_REGIONID, static_region);
 57
 58	rom->offset = intel_uncore_read(rom->uncore, OROM_OFFSET) & OROM_OFFSET_MASK;
 59
 60	rom->size = 0x200000;
 61
 62	rom->read32 = spi_read32;
 63	rom->read16 = spi_read16;
 64
 65	return rom;
 66}
 67
 68static u32 pci_read32(struct intel_rom *rom, loff_t offset)
 69{
 70	return ioread32(rom->oprom + offset);
 71}
 72
 73static u16 pci_read16(struct intel_rom *rom, loff_t offset)
 74{
 75	return ioread16(rom->oprom + offset);
 76}
 77
 78static void pci_read_block(struct intel_rom *rom, void *data,
 79			   loff_t offset, size_t size)
 80{
 81	memcpy_fromio(data, rom->oprom + offset, size);
 82}
 83
 84static void pci_free(struct intel_rom *rom)
 85{
 86	pci_unmap_rom(rom->pdev, rom->oprom);
 87}
 88
 89struct intel_rom *intel_rom_pci(struct drm_device *drm)
 90{
 91	struct intel_rom *rom;
 92
 93	rom = kzalloc(sizeof(*rom), GFP_KERNEL);
 94	if (!rom)
 95		return NULL;
 96
 97	rom->pdev = to_pci_dev(drm->dev);
 98
 99	rom->oprom = pci_map_rom(rom->pdev, &rom->size);
100	if (!rom->oprom) {
101		kfree(rom);
102		return NULL;
103	}
104
105	rom->read32 = pci_read32;
106	rom->read16 = pci_read16;
107	rom->read_block = pci_read_block;
108	rom->free = pci_free;
109
110	return rom;
111}
112
113u32 intel_rom_read32(struct intel_rom *rom, loff_t offset)
114{
115	return rom->read32(rom, offset);
116}
117
118u16 intel_rom_read16(struct intel_rom *rom, loff_t offset)
119{
120	return rom->read16(rom, offset);
121}
122
123void intel_rom_read_block(struct intel_rom *rom, void *data,
124			  loff_t offset, size_t size)
125{
126	u32 *ptr = data;
127	loff_t index;
128
129	if (rom->read_block) {
130		rom->read_block(rom, data, offset, size);
131		return;
132	}
133
134	for (index = 0; index < size; index += 4)
135		*ptr++ = rom->read32(rom, offset + index);
136}
137
138loff_t intel_rom_find(struct intel_rom *rom, u32 needle)
139{
140	loff_t offset;
141
142	for (offset = 0; offset < rom->size; offset += 4) {
143		if (rom->read32(rom, offset) == needle)
144			return offset;
145	}
146
147	return -ENOENT;
148}
149
150size_t intel_rom_size(struct intel_rom *rom)
151{
152	return rom->size;
153}
154
155void intel_rom_free(struct intel_rom *rom)
156{
157	if (rom && rom->free)
158		rom->free(rom);
159
160	kfree(rom);
161}
~/ Read-only file preview.