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 12 struct 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 29 static 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 37 static u16 spi_read16(struct intel_rom *rom, loff_t offset) 38 { 39 return spi_read32(rom, offset) & 0xffff; 40 } 41 42 struct intel_rom *intel_rom_spi(struct drm_i915_private *i915) 43 { 44 struct intel_rom *rom; 45 u32 static_region; 46 47 rom = kzalloc(sizeof(*rom), GFP_KERNEL); 48 if (!rom) 49 return NULL; 50 51 rom->uncore = &i915->uncore; 52 53 static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS); 54 static_region &= OPTIONROM_SPI_REGIONID_MASK; 55 intel_uncore_write(rom->uncore, PRIMARY_SPI_REGIONID, static_region); 56 57 rom->offset = intel_uncore_read(rom->uncore, OROM_OFFSET) & OROM_OFFSET_MASK; 58 59 rom->size = 0x200000; 60 61 rom->read32 = spi_read32; 62 rom->read16 = spi_read16; 63 64 return rom; 65 } 66 67 static u32 pci_read32(struct intel_rom *rom, loff_t offset) 68 { 69 return ioread32(rom->oprom + offset); 70 } 71 72 static u16 pci_read16(struct intel_rom *rom, loff_t offset) 73 { 74 return ioread16(rom->oprom + offset); 75 } 76 77 static void pci_read_block(struct intel_rom *rom, void *data, 78 loff_t offset, size_t size) 79 { 80 memcpy_fromio(data, rom->oprom + offset, size); 81 } 82 83 static void pci_free(struct intel_rom *rom) 84 { 85 pci_unmap_rom(rom->pdev, rom->oprom); 86 } 87 88 struct intel_rom *intel_rom_pci(struct drm_i915_private *i915) 89 { 90 struct intel_rom *rom; 91 92 rom = kzalloc(sizeof(*rom), GFP_KERNEL); 93 if (!rom) 94 return NULL; 95 96 rom->pdev = to_pci_dev(i915->drm.dev); 97 98 rom->oprom = pci_map_rom(rom->pdev, &rom->size); 99 if (!rom->oprom) { 100 kfree(rom); 101 return NULL; 102 } 103 104 rom->read32 = pci_read32; 105 rom->read16 = pci_read16; 106 rom->read_block = pci_read_block; 107 rom->free = pci_free; 108 109 return rom; 110 } 111 112 u32 intel_rom_read32(struct intel_rom *rom, loff_t offset) 113 { 114 return rom->read32(rom, offset); 115 } 116 117 u16 intel_rom_read16(struct intel_rom *rom, loff_t offset) 118 { 119 return rom->read16(rom, offset); 120 } 121 122 void intel_rom_read_block(struct intel_rom *rom, void *data, 123 loff_t offset, size_t size) 124 { 125 u32 *ptr = data; 126 loff_t index; 127 128 if (rom->read_block) { 129 rom->read_block(rom, data, offset, size); 130 return; 131 } 132 133 for (index = 0; index < size; index += 4) 134 *ptr++ = rom->read32(rom, offset + index); 135 } 136 137 loff_t intel_rom_find(struct intel_rom *rom, u32 needle) 138 { 139 loff_t offset; 140 141 for (offset = 0; offset < rom->size; offset += 4) { 142 if (rom->read32(rom, offset) == needle) 143 return offset; 144 } 145 146 return -ENOENT; 147 } 148 149 size_t intel_rom_size(struct intel_rom *rom) 150 { 151 return rom->size; 152 } 153 154 void intel_rom_free(struct intel_rom *rom) 155 { 156 if (rom && rom->free) 157 rom->free(rom); 158 159 kfree(rom); 160 } 161