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