soc: Remove copyright notices
[coreboot.git] / src / soc / intel / common / block / itss / itss.c
blob00bf4923699ca66826f1debc486124e1955ddff3
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <stdint.h>
16 #include <commonlib/helpers.h>
17 #include <console/console.h>
18 #include <intelblocks/itss.h>
19 #include <intelblocks/pcr.h>
20 #include <soc/itss.h>
21 #include <soc/pcr_ids.h>
23 void itss_irq_init(uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG])
25 uint32_t regs[MAX_PXRC_CONFIG/sizeof(uint32_t)] = {0};
26 uint8_t index, byte;
28 /* Fill in all the PIRx routes into one array. */
29 for (index = 0; index < ARRAY_SIZE(regs); index++) {
30 for (byte = 0; byte < sizeof(uint32_t); byte++) {
31 uint8_t val = pch_interrupt_routing[index *
32 sizeof(uint32_t) + byte];
33 uint8_t irq = val & 0xf;
35 if ((irq <= 2) || (irq == 8) || (irq == 13))
36 regs[index] |= (0x80 << (8 * byte));
37 else
38 regs[index] |= (val << (8 * byte));
40 /* Access the routing register in 32 bit mode to make this
41 function suitable for both IOSF 1.0 (where only 32 bit access
42 is supported) and later versions of the interface. */
43 pcr_write32(PID_ITSS,
44 PCR_ITSS_PIRQA_ROUT + (index * sizeof(uint32_t)),
45 regs[index]);
49 void itss_clock_gate_8254(void)
51 const uint32_t cge8254_mask = (1 << 2);
53 pcr_rmw32(PID_ITSS, PCR_ITSS_ITSSPRC, ~cge8254_mask, cge8254_mask);
56 void itss_set_irq_polarity(int irq, int active_low)
58 uint32_t mask;
59 uint16_t reg;
60 const uint16_t port = PID_ITSS;
62 if (irq < 0 || irq > ITSS_MAX_IRQ)
63 return;
65 reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * (irq / IRQS_PER_IPC);
66 mask = 1 << (irq % IRQS_PER_IPC);
68 pcr_rmw32(port, reg, ~mask, (active_low ? mask : 0));
71 static uint32_t irq_snapshot[NUM_IPC_REGS];
73 void itss_snapshot_irq_polarities(int start, int end)
75 int i;
76 int reg_start;
77 int reg_end;
78 const uint16_t port = PID_ITSS;
80 if (start < 0 || start > ITSS_MAX_IRQ ||
81 end < 0 || end > ITSS_MAX_IRQ || end < start)
82 return;
84 reg_start = start / IRQS_PER_IPC;
85 reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
87 for (i = reg_start; i < reg_end; i++) {
88 uint16_t reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
89 irq_snapshot[i] = pcr_read32(port, reg);
93 static void show_irq_polarities(const char *msg)
95 int i;
96 const uint16_t port = PID_ITSS;
98 printk(BIOS_INFO, "ITSS IRQ Polarities %s:\n", msg);
99 for (i = 0; i < NUM_IPC_REGS; i++) {
100 uint16_t reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
101 printk(BIOS_INFO, "IPC%d: 0x%08x\n", i, pcr_read32(port, reg));
105 void itss_restore_irq_polarities(int start, int end)
107 int i;
108 int reg_start;
109 int reg_end;
110 const uint16_t port = PID_ITSS;
112 if (start < 0 || start > ITSS_MAX_IRQ ||
113 end < 0 || end > ITSS_MAX_IRQ || end < start)
114 return;
116 show_irq_polarities("Before");
118 reg_start = start / IRQS_PER_IPC;
119 reg_end = (end + IRQS_PER_IPC - 1) / IRQS_PER_IPC;
121 for (i = reg_start; i < reg_end; i++) {
122 uint32_t mask;
123 uint16_t reg;
124 int irq_start;
125 int irq_end;
127 irq_start = i * IRQS_PER_IPC;
128 irq_end = MIN(irq_start + IRQS_PER_IPC - 1, ITSS_MAX_IRQ);
130 if (start > irq_end)
131 continue;
132 if (end < irq_start)
133 break;
135 /* Track bits within the bounds of of the register. */
136 irq_start = MAX(start, irq_start) % IRQS_PER_IPC;
137 irq_end = MIN(end, irq_end) % IRQS_PER_IPC;
139 /* Create bitmask of the inclusive range of start and end. */
140 mask = (((1U << irq_end) - 1) | (1U << irq_end));
141 mask &= ~((1U << irq_start) - 1);
143 reg = PCR_ITSS_IPC0_CONF + sizeof(uint32_t) * i;
144 pcr_rmw32(port, reg, ~mask, (mask & irq_snapshot[i]));
147 show_irq_polarities("After");