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_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 68 static u32 pci_read32(struct intel_rom *rom, loff_t offset) 69 { 70 return ioread32(rom->oprom + offset); 71 } 72 73 static u16 pci_read16(struct intel_rom *rom, loff_t offset) 74 { 75 return ioread16(rom->oprom + offset); 76 } 77 78 static 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 84 static void pci_free(struct intel_rom *rom) 85 { 86 pci_unmap_rom(rom->pdev, rom->oprom); 87 } 88 89 struct 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 113 u32 intel_rom_read32(struct intel_rom *rom, loff_t offset) 114 { 115 return rom->read32(rom, offset); 116 } 117 118 u16 intel_rom_read16(struct intel_rom *rom, loff_t offset) 119 { 120 return rom->read16(rom, offset); 121 } 122 123 void 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 138 loff_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 150 size_t intel_rom_size(struct intel_rom *rom) 151 { 152 return rom->size; 153 } 154 155 void intel_rom_free(struct intel_rom *rom) 156 { 157 if (rom && rom->free) 158 rom->free(rom); 159 160 kfree(rom); 161 } 162