Loading...
Note: File does not exist in v3.1.
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_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
67static u32 pci_read32(struct intel_rom *rom, loff_t offset)
68{
69 return ioread32(rom->oprom + offset);
70}
71
72static u16 pci_read16(struct intel_rom *rom, loff_t offset)
73{
74 return ioread16(rom->oprom + offset);
75}
76
77static 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
83static void pci_free(struct intel_rom *rom)
84{
85 pci_unmap_rom(rom->pdev, rom->oprom);
86}
87
88struct 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
112u32 intel_rom_read32(struct intel_rom *rom, loff_t offset)
113{
114 return rom->read32(rom, offset);
115}
116
117u16 intel_rom_read16(struct intel_rom *rom, loff_t offset)
118{
119 return rom->read16(rom, offset);
120}
121
122void 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
137loff_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
149size_t intel_rom_size(struct intel_rom *rom)
150{
151 return rom->size;
152}
153
154void intel_rom_free(struct intel_rom *rom)
155{
156 if (rom && rom->free)
157 rom->free(rom);
158
159 kfree(rom);
160}