coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
itss.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdint.h>
4 #include <commonlib/helpers.h>
5 #include <console/console.h>
6 #include <intelblocks/itss.h>
7 #include <intelblocks/pcr.h>
8 #include <soc/itss.h>
9 #include <soc/pcr_ids.h>
11 
13 {
14  uint32_t regs[PIRQ_COUNT/sizeof(uint32_t)] = {0};
15  uint8_t index, byte;
16 
17  /* Fill in all the PIRx routes into one array. */
18  for (index = 0; index < ARRAY_SIZE(regs); index++) {
19  for (byte = 0; byte < sizeof(uint32_t); byte++) {
21  sizeof(uint32_t) + byte];
22  uint8_t irq = val & 0xf;
23 
24  if ((irq <= 2) || (irq == 8) || (irq == 13))
25  regs[index] |= (0x80 << (8 * byte));
26  else
27  regs[index] |= (val << (8 * byte));
28  }
29  /* Access the routing register in 32 bit mode to make this
30  function suitable for both IOSF 1.0 (where only 32 bit access
31  is supported) and later versions of the interface. */
33  PCR_ITSS_PIRQA_ROUT + (index * sizeof(uint32_t)),
34  regs[index]);
35  }
36 }
37 
39 {
40  const uint32_t cge8254_mask = (1 << 2);
41 
42  pcr_rmw32(PID_ITSS, PCR_ITSS_ITSSPRC, ~cge8254_mask, cge8254_mask);
43 }
44 
45 void itss_set_irq_polarity(int irq, int active_low)
46 {
47  uint32_t mask;
48  uint16_t reg;
49  const uint16_t port = PID_ITSS;
50 
51  if (irq < 0 || irq > ITSS_MAX_IRQ)
52  return;
53 
54  reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * (irq / IRQS_PER_IPC);
55  mask = 1 << (irq % IRQS_PER_IPC);
56 
57  pcr_rmw32(port, reg, ~mask, (active_low ? mask : 0));
58 }
59 
61 
62 void itss_snapshot_irq_polarities(int start, int end)
63 {
64  int i;
65  int reg_start;
66  int reg_end;
67  const uint16_t port = PID_ITSS;
68 
69  if (start < 0 || start > ITSS_MAX_IRQ ||
70  end < 0 || end > ITSS_MAX_IRQ || end < start)
71  return;
72 
73  reg_start = start / IRQS_PER_IPC;
74  reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
75 
76  for (i = reg_start; i < reg_end; i++) {
77  uint16_t reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
78  irq_snapshot[i] = pcr_read32(port, reg);
79  }
80 }
81 
82 static void show_irq_polarities(const char *msg)
83 {
84  int i;
85  const uint16_t port = PID_ITSS;
86 
87  printk(BIOS_INFO, "ITSS IRQ Polarities %s:\n", msg);
88  for (i = 0; i < NUM_IPC_REGS; i++) {
89  uint16_t reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
90  printk(BIOS_INFO, "IPC%d: 0x%08x\n", i, pcr_read32(port, reg));
91  }
92 }
93 
94 void itss_restore_irq_polarities(int start, int end)
95 {
96  int i;
97  int reg_start;
98  int reg_end;
99  const uint16_t port = PID_ITSS;
100 
101  if (start < 0 || start > ITSS_MAX_IRQ ||
102  end < 0 || end > ITSS_MAX_IRQ || end < start)
103  return;
104 
105  show_irq_polarities("Before");
106 
107  reg_start = start / IRQS_PER_IPC;
108  reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
109 
110  for (i = reg_start; i < reg_end; i++) {
111  uint32_t mask;
112  uint16_t reg;
113  int irq_start;
114  int irq_end;
115 
116  irq_start = i * IRQS_PER_IPC;
117  irq_end = MIN(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
118 
119  if (start > irq_end)
120  continue;
121  if (end < irq_start)
122  break;
123 
124  /* Track bits within the bounds of the register. */
125  irq_start = MAX(start, irq_start) % IRQS_PER_IPC;
126  irq_end = MIN(end, irq_end) % IRQS_PER_IPC;
127 
128  /* Create bitmask of the inclusive range of start and end. */
129  mask = (((1U << irq_end) - 1) | (1U << irq_end));
130  mask &= ~((1U << irq_start) - 1);
131 
132  reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
133  pcr_rmw32(port, reg, ~mask, (mask & irq_snapshot[i]));
134  }
135 
136  show_irq_polarities("After");
137 }
@ PIRQ_COUNT
Definition: acpi_pirq_gen.h:30
#define ITSS_MAX_IRQ
Definition: itss.h:9
#define NUM_IPC_REGS
Definition: itss.h:11
#define IRQS_PER_IPC
Definition: itss.h:10
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MIN(a, b)
Definition: helpers.h:37
#define MAX(a, b)
Definition: helpers.h:40
#define PCR_ITSS_IPC0_CONF
Definition: itss.h:23
#define PCR_ITSS_ITSSPRC
Definition: itss.h:25
#define PCR_ITSS_PIRQA_ROUT
Definition: itss.h:7
void pcr_write32(uint8_t pid, uint16_t offset, uint32_t indata)
Definition: pcr.c:124
void pcr_rmw32(uint8_t pid, uint16_t offset, uint32_t anddata, uint32_t ordata)
Definition: pcr.c:154
uint32_t pcr_read32(uint8_t pid, uint16_t offset)
Definition: pcr.c:89
#define printk(level,...)
Definition: stdlib.h:16
@ PID_ITSS
Definition: pcr.h:16
port
Definition: i915.h:29
void itss_clock_gate_8254(void)
Definition: itss.c:38
void itss_snapshot_irq_polarities(int start, int end)
Definition: itss.c:62
void itss_restore_irq_polarities(int start, int end)
Definition: itss.c:94
static void show_irq_polarities(const char *msg)
Definition: itss.c:82
static uint32_t irq_snapshot[NUM_IPC_REGS]
Definition: itss.c:60
void itss_set_irq_polarity(int irq, int active_low)
Definition: itss.c:45
void itss_irq_init(const uint8_t pch_interrupt_routing[PIRQ_COUNT])
Definition: itss.c:12
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
static const uint8_t pch_interrupt_routing[PIRQ_COUNT]
Definition: lpc_lib.c:315
static const int mask[4]
Definition: gpio.c:308
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
u8 val
Definition: sys.c:300