blob: 1dadc8e6db83a507e7f997932bc9d52b75268abc [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +01002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpigen.h>
Tim Wawrzynczak53d08b62021-03-01 14:42:57 -07004#include <acpi/acpigen_pci.h>
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +01005#include <device/pci_def.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +02006#include <device/pci_ops.h>
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +01007
8#include "acpi_pirq_gen.h"
9
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070010static void gen_apic_route(const struct slot_pin_irq_map *pin_irq_map,
11 unsigned int map_count)
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010012{
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070013 for (unsigned int i = 0; i < map_count; i++)
14 /*
15 * The reason for subtracting PCI_INT_A from the pin given is
16 * that PCI defines pins as 1-4, and _PRT uses 0-3.
17 */
18 acpigen_write_PRT_GSI_entry(pin_irq_map[i].slot,
19 pin_irq_map[i].pin - PCI_INT_A,
20 pin_irq_map[i].apic_gsi);
21}
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010022
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070023static void gen_pic_route(const struct slot_pin_irq_map *pin_irq_map,
24 unsigned int map_count,
25 const struct pic_pirq_map *pirq_map)
26{
27 for (unsigned int i = 0; i < map_count; i++) {
Tim Wawrzynczakef16df22021-06-05 11:38:14 -060028 const enum pirq pirq = pin_irq_map[i].pic_pirq;
29 const unsigned int pin = pin_irq_map[i].pin - PCI_INT_A;
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070030 if (pirq == PIRQ_INVALID)
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010031 continue;
32
Tim Wawrzynczakef16df22021-06-05 11:38:14 -060033 const size_t pirq_index = pirq_idx(pirq);
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070034 if (pirq_map->type == PIRQ_GSI)
35 acpigen_write_PRT_GSI_entry(pin_irq_map[i].slot,
36 pin,
Tim Wawrzynczakef16df22021-06-05 11:38:14 -060037 pirq_map->gsi[pirq_index]);
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070038 else
39 acpigen_write_PRT_source_entry(pin_irq_map[i].slot,
40 pin,
Tim Wawrzynczakef16df22021-06-05 11:38:14 -060041 pirq_map->source_path[pirq_index],
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070042 0);
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010043 }
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010044}
45
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070046void intel_write_pci0_PRT(const struct slot_pin_irq_map *pin_irq_map,
47 unsigned int map_count,
48 const struct pic_pirq_map *pirq_map)
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010049{
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070050 /* \_SB.PCI0._PRT */
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010051 acpigen_write_scope("\\_SB.PCI0");
52 acpigen_write_method("_PRT", 0);
53 acpigen_write_if();
54 acpigen_emit_namestring("PICM");
55 acpigen_emit_byte(RETURN_OP);
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070056 acpigen_write_package(map_count);
57 gen_apic_route(pin_irq_map, map_count);
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010058 acpigen_pop_len(); /* package */
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010059 acpigen_write_else();
60 acpigen_emit_byte(RETURN_OP);
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070061 acpigen_write_package(map_count);
62 gen_pic_route(pin_irq_map, map_count, pirq_map);
Tobias Diedrich9d8be5a2017-12-13 23:25:32 +010063 acpigen_pop_len(); /* package */
64 acpigen_pop_len(); /* else PICM */
65 acpigen_pop_len(); /* _PRT */
66 acpigen_pop_len(); /* \_SB */
67}
Tim Wawrzynczakf62c4942021-02-26 10:30:52 -070068
69bool is_slot_pin_assigned(const struct slot_pin_irq_map *pin_irq_map,
70 unsigned int map_count, unsigned int slot,
71 enum pci_pin pin)
72{
73 for (size_t i = 0; i < map_count; i++) {
74 if (pin_irq_map[i].slot == slot && pin_irq_map[i].pin == pin)
75 return true;
76 }
77
78 return false;
79}