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