drivers/ipmi: Add IPMI read FRU chassis info area
[coreboot.git] / src / device / pnp_device.c
blobcd7adf32bc51ccd78af54adf3987d90b426d919a
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <stdint.h>
5 #include <arch/io.h>
6 #include <device/device.h>
7 #include <device/pnp.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_set_logical_device(struct device *dev)
52 pnp_write_config(dev, 0x07, dev->path.pnp.device & 0xff);
55 void pnp_set_enable(struct device *dev, int enable)
57 u8 tmp, bitpos;
59 tmp = pnp_read_config(dev, 0x30);
61 /* Handle virtual devices, which share the same LDN register. */
62 bitpos = (dev->path.pnp.device >> 8) & 0x7;
64 if (enable)
65 tmp |= (1 << bitpos);
66 else
67 tmp &= ~(1 << bitpos);
69 pnp_write_config(dev, 0x30, tmp);
72 int pnp_read_enable(struct device *dev)
74 u8 tmp, bitpos;
76 tmp = pnp_read_config(dev, 0x30);
78 /* Handle virtual devices, which share the same LDN register. */
79 bitpos = (dev->path.pnp.device >> 8) & 0x7;
81 return !!(tmp & (1 << bitpos));
84 void pnp_set_iobase(struct device *dev, u8 index, u16 iobase)
86 /* Index == 0x60 or 0x62. */
87 pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
88 pnp_write_config(dev, index + 1, iobase & 0xff);
91 void pnp_set_irq(struct device *dev, u8 index, u8 irq)
93 /* Index == 0x70 or 0x72. */
94 pnp_write_config(dev, index, irq);
97 void pnp_set_drq(struct device *dev, u8 index, u8 drq)
99 /* Index == 0x74. */
100 pnp_write_config(dev, index, drq & 0xff);
103 /* PNP device operations */
105 void pnp_read_resources(struct device *dev)
107 return;
110 static void pnp_set_resource(struct device *dev, struct resource *resource)
112 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
113 /* The PNP_MSC Super IO registers have the IRQ flag set. If no
114 value is assigned in the devicetree, the corresponding
115 PNP_MSC register doesn't get written, which should be printed
116 as warning and not as error. */
117 if (resource->flags & IORESOURCE_IRQ &&
118 (resource->index != PNP_IDX_IRQ0) &&
119 (resource->index != PNP_IDX_IRQ1))
120 printk(BIOS_WARNING, "WARNING: %s %02lx %s size: "
121 "0x%010llx not assigned in devicetree\n", dev_path(dev),
122 resource->index, resource_type(resource),
123 resource->size);
124 else
125 printk(BIOS_ERR, "ERROR: %s %02lx %s size: 0x%010llx "
126 "not assigned in devicetree\n", dev_path(dev), resource->index,
127 resource_type(resource), resource->size);
128 return;
131 /* Now store the resource. */
132 if (resource->flags & IORESOURCE_IO) {
133 pnp_set_iobase(dev, resource->index, resource->base);
134 } else if (resource->flags & IORESOURCE_DRQ) {
135 pnp_set_drq(dev, resource->index, resource->base);
136 } else if (resource->flags & IORESOURCE_IRQ) {
137 pnp_set_irq(dev, resource->index, resource->base);
138 } else {
139 printk(BIOS_ERR, "ERROR: %s %02lx unknown resource type\n",
140 dev_path(dev), resource->index);
141 return;
143 resource->flags |= IORESOURCE_STORED;
145 report_resource_stored(dev, resource, "");
148 void pnp_set_resources(struct device *dev)
150 struct resource *res;
152 pnp_enter_conf_mode(dev);
154 /* Select the logical device (LDN). */
155 pnp_set_logical_device(dev);
157 /* Paranoia says I should disable the device here... */
158 for (res = dev->resource_list; res; res = res->next)
159 pnp_set_resource(dev, res);
161 pnp_exit_conf_mode(dev);
164 void pnp_enable_resources(struct device *dev)
166 pnp_enter_conf_mode(dev);
167 pnp_set_logical_device(dev);
168 pnp_set_enable(dev, 1);
169 pnp_exit_conf_mode(dev);
172 void pnp_enable(struct device *dev)
174 if (!dev->enabled) {
175 pnp_enter_conf_mode(dev);
176 pnp_set_logical_device(dev);
177 pnp_set_enable(dev, 0);
178 pnp_exit_conf_mode(dev);
182 void pnp_alt_enable(struct device *dev)
184 pnp_enter_conf_mode(dev);
185 pnp_set_logical_device(dev);
186 pnp_set_enable(dev, !!dev->enabled);
187 pnp_exit_conf_mode(dev);
190 struct device_operations pnp_ops = {
191 .read_resources = pnp_read_resources,
192 .set_resources = pnp_set_resources,
193 .enable_resources = pnp_enable_resources,
194 .enable = pnp_enable,
197 /* PNP chip operations */
199 static void pnp_get_ioresource(struct device *dev, u8 index, u16 mask)
201 struct resource *resource;
202 unsigned int bit;
204 /* If none of the mask bits is set, the resource would occupy the whole
205 IO space leading to IO resource conflicts with the other devices */
206 if (!mask) {
207 printk(BIOS_ERR, "ERROR: device %s index %d has no mask.\n",
208 dev_path(dev), index);
209 return;
212 resource = new_resource(dev, index);
213 resource->flags |= IORESOURCE_IO;
215 /* Calculate IO region size which is determined by the first one from
216 the LSB of the mask. */
217 for (bit = 0; bit <= 15 && (mask & (1 << bit)) == 0; ++bit)
220 resource->gran = bit;
221 resource->align = bit;
222 resource->size = 1 << bit;
224 /* Calculate IO region address limit which is determined by the first
225 one from the MSB of the mask. */
226 for (bit = 15; bit != 0 && (mask & (1 << bit)) == 0; --bit)
229 resource->limit = (1 << (bit + 1)) - 1;
231 /* The block of ones in the mask is expected to be continuous.
232 If there is any zero inbetween the block of ones, it is ignored
233 in the calculation of the resource size and limit. */
234 if (mask != (resource->limit ^ (resource->size - 1)))
235 printk(BIOS_WARNING,
236 "WARNING: mask of device %s index %d is wrong.\n",
237 dev_path(dev), index);
240 static void get_resources(struct device *dev, struct pnp_info *info)
242 struct resource *resource;
244 if (info->flags & PNP_IO0)
245 pnp_get_ioresource(dev, PNP_IDX_IO0, info->io0);
246 if (info->flags & PNP_IO1)
247 pnp_get_ioresource(dev, PNP_IDX_IO1, info->io1);
248 if (info->flags & PNP_IO2)
249 pnp_get_ioresource(dev, PNP_IDX_IO2, info->io2);
250 if (info->flags & PNP_IO3)
251 pnp_get_ioresource(dev, PNP_IDX_IO3, info->io3);
253 if (info->flags & PNP_IRQ0) {
254 resource = new_resource(dev, PNP_IDX_IRQ0);
255 resource->size = 1;
256 resource->flags |= IORESOURCE_IRQ;
258 if (info->flags & PNP_IRQ1) {
259 resource = new_resource(dev, PNP_IDX_IRQ1);
260 resource->size = 1;
261 resource->flags |= IORESOURCE_IRQ;
264 if (info->flags & PNP_DRQ0) {
265 resource = new_resource(dev, PNP_IDX_DRQ0);
266 resource->size = 1;
267 resource->flags |= IORESOURCE_DRQ;
269 if (info->flags & PNP_DRQ1) {
270 resource = new_resource(dev, PNP_IDX_DRQ1);
271 resource->size = 1;
272 resource->flags |= IORESOURCE_DRQ;
276 * These are not IRQs, but set the flag to have the
277 * resource allocator do the right thing.
279 if (info->flags & PNP_EN) {
280 resource = new_resource(dev, PNP_IDX_EN);
281 resource->size = 1;
282 resource->flags |= IORESOURCE_IRQ;
284 if (info->flags & PNP_MSC0) {
285 resource = new_resource(dev, PNP_IDX_MSC0);
286 resource->size = 1;
287 resource->flags |= IORESOURCE_IRQ;
289 if (info->flags & PNP_MSC1) {
290 resource = new_resource(dev, PNP_IDX_MSC1);
291 resource->size = 1;
292 resource->flags |= IORESOURCE_IRQ;
294 if (info->flags & PNP_MSC2) {
295 resource = new_resource(dev, PNP_IDX_MSC2);
296 resource->size = 1;
297 resource->flags |= IORESOURCE_IRQ;
299 if (info->flags & PNP_MSC3) {
300 resource = new_resource(dev, PNP_IDX_MSC3);
301 resource->size = 1;
302 resource->flags |= IORESOURCE_IRQ;
304 if (info->flags & PNP_MSC4) {
305 resource = new_resource(dev, PNP_IDX_MSC4);
306 resource->size = 1;
307 resource->flags |= IORESOURCE_IRQ;
309 if (info->flags & PNP_MSC5) {
310 resource = new_resource(dev, PNP_IDX_MSC5);
311 resource->size = 1;
312 resource->flags |= IORESOURCE_IRQ;
314 if (info->flags & PNP_MSC6) {
315 resource = new_resource(dev, PNP_IDX_MSC6);
316 resource->size = 1;
317 resource->flags |= IORESOURCE_IRQ;
319 if (info->flags & PNP_MSC7) {
320 resource = new_resource(dev, PNP_IDX_MSC7);
321 resource->size = 1;
322 resource->flags |= IORESOURCE_IRQ;
324 if (info->flags & PNP_MSC8) {
325 resource = new_resource(dev, PNP_IDX_MSC8);
326 resource->size = 1;
327 resource->flags |= IORESOURCE_IRQ;
329 if (info->flags & PNP_MSC9) {
330 resource = new_resource(dev, PNP_IDX_MSC9);
331 resource->size = 1;
332 resource->flags |= IORESOURCE_IRQ;
334 if (info->flags & PNP_MSCA) {
335 resource = new_resource(dev, PNP_IDX_MSCA);
336 resource->size = 1;
337 resource->flags |= IORESOURCE_IRQ;
339 if (info->flags & PNP_MSCB) {
340 resource = new_resource(dev, PNP_IDX_MSCB);
341 resource->size = 1;
342 resource->flags |= IORESOURCE_IRQ;
344 if (info->flags & PNP_MSCC) {
345 resource = new_resource(dev, PNP_IDX_MSCC);
346 resource->size = 1;
347 resource->flags |= IORESOURCE_IRQ;
349 if (info->flags & PNP_MSCD) {
350 resource = new_resource(dev, PNP_IDX_MSCD);
351 resource->size = 1;
352 resource->flags |= IORESOURCE_IRQ;
354 if (info->flags & PNP_MSCE) {
355 resource = new_resource(dev, PNP_IDX_MSCE);
356 resource->size = 1;
357 resource->flags |= IORESOURCE_IRQ;
361 void pnp_enable_devices(struct device *base_dev, struct device_operations *ops,
362 unsigned int functions, struct pnp_info *info)
364 struct device_path path;
365 struct device *dev;
366 int i;
368 path.type = DEVICE_PATH_PNP;
369 path.pnp.port = base_dev->path.pnp.port;
371 /* Setup the ops and resources on the newly allocated devices. */
372 for (i = 0; i < functions; i++) {
373 /* Skip logical devices this Super I/O doesn't have. */
374 if (info[i].function == PNP_SKIP_FUNCTION)
375 continue;
377 path.pnp.device = info[i].function;
378 dev = alloc_find_dev(base_dev->bus, &path);
380 /* Don't initialize a device multiple times. */
381 if (dev->ops)
382 continue;
384 /* use LDN-specific ops override from corresponding pnp_info
385 entry if not NULL */
386 if (info[i].ops)
387 dev->ops = info[i].ops;
388 /* else use device ops */
389 else
390 dev->ops = ops;
392 get_resources(dev, &info[i]);