cpu/x86/smm/pci_resource_store: Store DEV/VEN ID
[coreboot2.git] / src / device / pnp_device.c
blobf799530d8e6c54caaaab5e731be957de5771da80
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/io.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pnp.h>
7 #include <stdint.h>
9 /* PNP config mode wrappers */
11 void pnp_enter_conf_mode(struct device *dev)
13 if (dev->ops->ops_pnp_mode)
14 dev->ops->ops_pnp_mode->enter_conf_mode(dev);
17 void pnp_exit_conf_mode(struct device *dev)
19 if (dev->ops->ops_pnp_mode)
20 dev->ops->ops_pnp_mode->exit_conf_mode(dev);
23 #if CONFIG(HAVE_ACPI_TABLES)
24 void pnp_ssdt_enter_conf_mode(struct device *dev, const char *idx, const char *data)
26 if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_enter_conf_mode)
27 dev->ops->ops_pnp_mode->ssdt_enter_conf_mode(dev, idx, data);
29 void pnp_ssdt_exit_conf_mode(struct device *dev, const char *idx, const char *data)
31 if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_exit_conf_mode)
32 dev->ops->ops_pnp_mode->ssdt_exit_conf_mode(dev, idx, data);
34 #endif
36 /* PNP fundamental operations */
38 void pnp_write_config(struct device *dev, u8 reg, u8 value)
40 outb(reg, dev->path.pnp.port);
41 outb(value, dev->path.pnp.port + 1);
44 u8 pnp_read_config(struct device *dev, u8 reg)
46 outb(reg, dev->path.pnp.port);
47 return inb(dev->path.pnp.port + 1);
50 void pnp_unset_and_set_config(struct device *dev, u8 reg, u8 unset, u8 set)
52 outb(reg, dev->path.pnp.port);
53 u8 value = inb(dev->path.pnp.port + 1);
54 value &= ~unset;
55 value |= set;
56 outb(value, dev->path.pnp.port + 1);
59 void pnp_set_logical_device(struct device *dev)
61 pnp_write_config(dev, 0x07, dev->path.pnp.device & 0xff);
64 void pnp_set_enable(struct device *dev, int enable)
66 u8 tmp, bitpos;
68 tmp = pnp_read_config(dev, PNP_IDX_EN);
70 /* Handle virtual devices, which share the same LDN register. */
71 bitpos = (dev->path.pnp.device >> 8) & 0x7;
73 if (enable)
74 tmp |= (1 << bitpos);
75 else
76 tmp &= ~(1 << bitpos);
78 pnp_write_config(dev, PNP_IDX_EN, tmp);
81 int pnp_read_enable(struct device *dev)
83 u8 tmp, bitpos;
85 tmp = pnp_read_config(dev, PNP_IDX_EN);
87 /* Handle virtual devices, which share the same LDN register. */
88 bitpos = (dev->path.pnp.device >> 8) & 0x7;
90 return !!(tmp & (1 << bitpos));
93 void pnp_set_iobase(struct device *dev, u8 index, u16 iobase)
95 /* Index == 0x60 or 0x62. */
96 pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
97 pnp_write_config(dev, index + 1, iobase & 0xff);
100 void pnp_set_irq(struct device *dev, u8 index, u8 irq)
102 /* Index == 0x70 or 0x72. */
103 pnp_write_config(dev, index, irq);
106 void pnp_set_drq(struct device *dev, u8 index, u8 drq)
108 /* Index == 0x74. */
109 pnp_write_config(dev, index, drq & 0xff);
112 /* PNP device operations */
114 void pnp_read_resources(struct device *dev)
118 static void pnp_set_resource(struct device *dev, struct resource *resource)
120 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
121 /* The PNP_MSC Super IO registers have the IRQ flag set. If no
122 value is assigned in the devicetree, the corresponding
123 PNP_MSC register doesn't get written, which should be printed
124 as warning and not as error. */
125 if (resource->flags & IORESOURCE_IRQ &&
126 (resource->index != PNP_IDX_IRQ0) &&
127 (resource->index != PNP_IDX_IRQ1))
128 printk(BIOS_WARNING, "%s %02lx %s size: "
129 "0x%010llx not assigned in devicetree\n", dev_path(dev),
130 resource->index, resource_type(resource),
131 resource->size);
132 else
133 printk(BIOS_ERR, "%s %02lx %s size: 0x%010llx "
134 "not assigned in devicetree\n", dev_path(dev), resource->index,
135 resource_type(resource), resource->size);
136 return;
139 /* Now store the resource. */
140 if (resource->flags & IORESOURCE_IO) {
141 pnp_set_iobase(dev, resource->index, resource->base);
142 } else if (resource->flags & IORESOURCE_DRQ) {
143 pnp_set_drq(dev, resource->index, resource->base);
144 } else if (resource->flags & IORESOURCE_IRQ) {
145 pnp_set_irq(dev, resource->index, resource->base);
146 } else {
147 printk(BIOS_ERR, "%s %02lx unknown resource type\n",
148 dev_path(dev), resource->index);
149 return;
151 resource->flags |= IORESOURCE_STORED;
153 report_resource_stored(dev, resource, "");
156 void pnp_set_resources(struct device *dev)
158 struct resource *res;
160 pnp_enter_conf_mode(dev);
162 /* Select the logical device (LDN). */
163 pnp_set_logical_device(dev);
165 /* Paranoia says I should disable the device here... */
166 for (res = dev->resource_list; res; res = res->next)
167 pnp_set_resource(dev, res);
169 pnp_exit_conf_mode(dev);
172 void pnp_enable_resources(struct device *dev)
174 pnp_enter_conf_mode(dev);
175 pnp_set_logical_device(dev);
176 pnp_set_enable(dev, 1);
177 pnp_exit_conf_mode(dev);
180 void pnp_enable(struct device *dev)
182 if (!dev->enabled) {
183 pnp_enter_conf_mode(dev);
184 pnp_set_logical_device(dev);
185 pnp_set_enable(dev, 0);
186 pnp_exit_conf_mode(dev);
190 void pnp_alt_enable(struct device *dev)
192 pnp_enter_conf_mode(dev);
193 pnp_set_logical_device(dev);
194 pnp_set_enable(dev, !!dev->enabled);
195 pnp_exit_conf_mode(dev);
198 struct device_operations pnp_ops = {
199 .read_resources = pnp_read_resources,
200 .set_resources = pnp_set_resources,
201 .enable_resources = pnp_enable_resources,
202 .enable = pnp_enable,
205 /* PNP chip operations */
207 static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
209 struct resource *resource;
210 unsigned int bit;
212 /* If none of the mask bits is set, the resource would occupy the whole
213 IO space leading to IO resource conflicts with the other devices */
214 if (!mask) {
215 printk(BIOS_ERR, "device %s index %d has no mask.\n",
216 dev_path(dev), index);
217 return;
220 resource = new_resource(dev, index);
221 resource->flags |= IORESOURCE_IO;
223 /* Calculate IO region size which is determined by the first one from
224 the LSB of the mask. */
225 for (bit = 0; bit <= 15 && (mask & (1 << bit)) == 0; ++bit)
228 resource->gran = bit;
229 resource->align = bit;
230 resource->size = 1 << bit;
232 /* Calculate IO region address limit which is determined by the first
233 one from the MSB of the mask. */
234 for (bit = 15; bit != 0 && (mask & (1 << bit)) == 0; --bit)
237 resource->limit = (1 << (bit + 1)) - 1;
239 /* The block of ones in the mask is expected to be continuous.
240 If there is any zero in between the block of ones, it is ignored
241 in the calculation of the resource size and limit. */
242 if (mask != (resource->limit ^ (resource->size - 1)))
243 printk(BIOS_WARNING, "mask of device %s index %d is wrong.\n",
244 dev_path(dev), index);
247 static void get_resources(struct device *dev, struct pnp_info *info)
249 struct resource *resource;
251 if (info->flags & PNP_IO0)
252 pnp_get_ioresource(dev, PNP_IDX_IO0, info->io0);
253 if (info->flags & PNP_IO1)
254 pnp_get_ioresource(dev, PNP_IDX_IO1, info->io1);
255 if (info->flags & PNP_IO2)
256 pnp_get_ioresource(dev, PNP_IDX_IO2, info->io2);
257 if (info->flags & PNP_IO3)
258 pnp_get_ioresource(dev, PNP_IDX_IO3, info->io3);
259 if (info->flags & PNP_IO4)
260 pnp_get_ioresource(dev, PNP_IDX_IO4, info->io4);
262 if (info->flags & PNP_IRQ0) {
263 resource = new_resource(dev, PNP_IDX_IRQ0);
264 resource->size = 1;
265 resource->flags |= IORESOURCE_IRQ;
267 if (info->flags & PNP_IRQ1) {
268 resource = new_resource(dev, PNP_IDX_IRQ1);
269 resource->size = 1;
270 resource->flags |= IORESOURCE_IRQ;
273 if (info->flags & PNP_DRQ0) {
274 resource = new_resource(dev, PNP_IDX_DRQ0);
275 resource->size = 1;
276 resource->flags |= IORESOURCE_DRQ;
278 if (info->flags & PNP_DRQ1) {
279 resource = new_resource(dev, PNP_IDX_DRQ1);
280 resource->size = 1;
281 resource->flags |= IORESOURCE_DRQ;
285 * These are not IRQs, but set the flag to have the
286 * resource allocator do the right thing.
288 if (info->flags & PNP_EN) {
289 resource = new_resource(dev, PNP_IDX_EN);
290 resource->size = 1;
291 resource->flags |= IORESOURCE_IRQ;
293 if (info->flags & PNP_MSC0) {
294 resource = new_resource(dev, PNP_IDX_MSC0);
295 resource->size = 1;
296 resource->flags |= IORESOURCE_IRQ;
298 if (info->flags & PNP_MSC1) {
299 resource = new_resource(dev, PNP_IDX_MSC1);
300 resource->size = 1;
301 resource->flags |= IORESOURCE_IRQ;
303 if (info->flags & PNP_MSC2) {
304 resource = new_resource(dev, PNP_IDX_MSC2);
305 resource->size = 1;
306 resource->flags |= IORESOURCE_IRQ;
308 if (info->flags & PNP_MSC3) {
309 resource = new_resource(dev, PNP_IDX_MSC3);
310 resource->size = 1;
311 resource->flags |= IORESOURCE_IRQ;
313 if (info->flags & PNP_MSC4) {
314 resource = new_resource(dev, PNP_IDX_MSC4);
315 resource->size = 1;
316 resource->flags |= IORESOURCE_IRQ;
318 if (info->flags & PNP_MSC5) {
319 resource = new_resource(dev, PNP_IDX_MSC5);
320 resource->size = 1;
321 resource->flags |= IORESOURCE_IRQ;
323 if (info->flags & PNP_MSC6) {
324 resource = new_resource(dev, PNP_IDX_MSC6);
325 resource->size = 1;
326 resource->flags |= IORESOURCE_IRQ;
328 if (info->flags & PNP_MSC7) {
329 resource = new_resource(dev, PNP_IDX_MSC7);
330 resource->size = 1;
331 resource->flags |= IORESOURCE_IRQ;
333 if (info->flags & PNP_MSC8) {
334 resource = new_resource(dev, PNP_IDX_MSC8);
335 resource->size = 1;
336 resource->flags |= IORESOURCE_IRQ;
338 if (info->flags & PNP_MSC9) {
339 resource = new_resource(dev, PNP_IDX_MSC9);
340 resource->size = 1;
341 resource->flags |= IORESOURCE_IRQ;
343 if (info->flags & PNP_MSCA) {
344 resource = new_resource(dev, PNP_IDX_MSCA);
345 resource->size = 1;
346 resource->flags |= IORESOURCE_IRQ;
348 if (info->flags & PNP_MSCB) {
349 resource = new_resource(dev, PNP_IDX_MSCB);
350 resource->size = 1;
351 resource->flags |= IORESOURCE_IRQ;
353 if (info->flags & PNP_MSCC) {
354 resource = new_resource(dev, PNP_IDX_MSCC);
355 resource->size = 1;
356 resource->flags |= IORESOURCE_IRQ;
358 if (info->flags & PNP_MSCD) {
359 resource = new_resource(dev, PNP_IDX_MSCD);
360 resource->size = 1;
361 resource->flags |= IORESOURCE_IRQ;
363 if (info->flags & PNP_MSCE) {
364 resource = new_resource(dev, PNP_IDX_MSCE);
365 resource->size = 1;
366 resource->flags |= IORESOURCE_IRQ;
370 void pnp_enable_devices(struct device *base_dev, struct device_operations *ops,
371 unsigned int functions, struct pnp_info *info)
373 struct device_path path;
374 struct device *dev;
375 int i;
377 path.type = DEVICE_PATH_PNP;
378 path.pnp.port = base_dev->path.pnp.port;
380 /* Setup the ops and resources on the newly allocated devices. */
381 for (i = 0; i < functions; i++) {
382 /* Skip logical devices this Super I/O doesn't have. */
383 if (info[i].function == PNP_SKIP_FUNCTION)
384 continue;
386 path.pnp.device = info[i].function;
387 dev = alloc_find_dev(base_dev->upstream, &path);
389 /* Don't initialize a device multiple times. */
390 if (dev->ops)
391 continue;
393 /* use LDN-specific ops override from corresponding pnp_info
394 entry if not NULL */
395 if (info[i].ops)
396 dev->ops = info[i].ops;
397 /* else use device ops */
398 else
399 dev->ops = ops;
401 get_resources(dev, &info[i]);