MAINTAINERS: Add Maximilian Brune to RISC-V
[coreboot.git] / util / autoport / lynxpoint_lp_gpio.go
blobee5944c91da2b96c00734d0abea8b88f9d132102
1 package main
3 import (
4 "fmt"
5 "os"
6 "strings"
9 const (
10 PIRQI = 0
11 PIRQJ = 1
12 PIRQK = 2
13 PIRQL = 3
14 PIRQM = 4
15 PIRQN = 5
16 PIRQO = 6
17 PIRQP = 7
18 PIRQQ = 8
19 PIRQR = 9
20 PIRQS = 10
21 PIRQT = 11
22 PIRQU = 12
23 PIRQV = 13
24 PIRQW = 14
25 PIRQX = 15
28 /* from sb/intel/lynxpoint/lp_gpio.c */
29 func lp_gpio_to_pirq(gpioNum uint16) int {
30 var pirqmap = map[uint16] int {
31 8: PIRQI,
32 9: PIRQJ,
33 10: PIRQK,
34 13: PIRQL,
35 14: PIRQM,
36 45: PIRQN,
37 46: PIRQO,
38 47: PIRQP,
39 48: PIRQQ,
40 49: PIRQR,
41 50: PIRQS,
42 51: PIRQT,
43 52: PIRQU,
44 53: PIRQV,
45 54: PIRQW,
46 55: PIRQX,
48 pirq, valid := pirqmap[gpioNum]
49 if (valid) {
50 return pirq
51 } else {
52 return -1
56 func conf0str(conf0 uint32) string {
57 if (conf0 & 1) == 0 {
58 return "GPIO_MODE_NATIVE"
59 } else {
60 s := []string{"GPIO_MODE_GPIO"}
61 var gpio_output bool
62 if ((conf0 >> 2) & 1) == 1 {
63 s = append(s, "GPIO_DIR_INPUT")
64 gpio_output = false
65 } else {
66 s = append(s, "GPIO_DIR_OUTPUT")
67 gpio_output = true
69 if ((conf0 >> 3) & 1) == 1 {
70 s = append(s, "GPIO_INVERT")
72 if ((conf0 >> 4) & 1) == 1 {
73 s = append(s, "GPIO_IRQ_LEVEL")
75 if gpio_output {
76 if ((conf0 >> 31) & 1) == 1 {
77 s = append(s, "GPO_LEVEL_HIGH")
78 } else {
79 s = append(s, "GPO_LEVEL_LOW")
82 return strings.Join(s, " | ")
86 func lpgpio_preset(conf0 uint32, owner uint32, route uint32, irqen uint32, pirq uint32) string {
87 if conf0 == 0xd { /* 0b1101: MODE_GPIO | INPUT | INVERT */
88 if owner == 0 { /* OWNER_ACPI */
89 if irqen == 0 && pirq == 0 {
90 if route == 0 { /* SCI */
91 return "GPIO_ACPI_SCI"
92 } else {
93 return "GPIO_ACPI_SMI"
96 return ""
97 } else { /* OWNER_GPIO */
98 if route == 0 && irqen == 0 && pirq != 0 {
99 return "GPIO_INPUT_INVERT"
101 return ""
105 if conf0 == 0x5 && owner == 1 { /* 0b101: MODE_GPIO | INPUT, OWNER_GPIO */
106 if route == 0 && irqen == 0 {
107 if pirq == 1 {
108 return "GPIO_PIRQ"
109 } else {
110 return "GPIO_INPUT"
113 return ""
116 if owner == 1 && irqen == 1 {
117 if route == 0 && pirq == 0 {
118 if conf0 == 0x5 { /* 0b00101 */
119 return "GPIO_IRQ_EDGE"
121 if conf0 == 0x15 { /* 0b10101 */
122 return "GPIO_IRQ_LEVEL"
125 return ""
127 return ""
130 func gpio_str(conf0 uint32, conf1 uint32, owner uint32, route uint32, irqen uint32, reset uint32, blink uint32, pirq uint32) string {
131 s := []string{}
132 s = append(s, fmt.Sprintf(".conf0 = %s", conf0str(conf0)))
133 if conf1 != 0 {
134 s = append(s, fmt.Sprintf(".conf1 = 0x%x", conf1))
136 if owner != 0 {
137 s = append(s, ".owner = GPIO_OWNER_GPIO")
139 if route != 0 {
140 s = append(s, ".route = GPIO_ROUTE_SMI")
142 if irqen != 0 {
143 s = append(s, ".irqen = GPIO_IRQ_ENABLE")
145 if reset != 0 {
146 s = append(s, ".reset = GPIO_RESET_RSMRST")
148 if blink != 0 {
149 s = append(s, ".blink = GPO_BLINK")
151 if pirq != 0 {
152 s = append(s, ".pirq = GPIO_PIRQ_APIC_ROUTE")
154 return strings.Join(s, ", ")
157 /* start addresses of GPIO registers */
158 const (
159 GPIO_OWN = 0x0
160 GPIPIRQ2IOXAPIC = 0x10
161 GPO_BLINK = 0x18
162 GPI_ROUT = 0x30
163 GP_RST_SEL = 0x60
164 GPI_IE = 0x90
165 GPnCONFIGA = 0x100
166 GPnCONFIGB = 0x104
169 func PrintLPGPIO(gpio *os.File, inteltool InteltoolData) {
170 for gpioNum := uint16(0); gpioNum <= 94; gpioNum++ {
171 if gpioNum < 10 {
172 fmt.Fprintf(gpio, "\t[%d] = ", gpioNum)
173 } else {
174 fmt.Fprintf(gpio, "\t[%d] = ", gpioNum)
176 conf0 := inteltool.GPIO[GPnCONFIGA+gpioNum*8]
177 conf1 := inteltool.GPIO[GPnCONFIGB+gpioNum*8]
178 set := gpioNum / 32
179 bit := gpioNum % 32
180 /* owner only effective in GPIO mode */
181 owner := (inteltool.GPIO[GPIO_OWN+set*4] >> bit) & 1
182 route := (inteltool.GPIO[GPI_ROUT+set*4] >> bit) & 1
183 irqen := (inteltool.GPIO[GPI_IE+set*4] >> bit) & 1
184 reset := (inteltool.GPIO[GP_RST_SEL+set*4] >> bit) & 1
185 var blink, pirq uint32
186 /* blink only effective in GPIO output mode */
187 if set == 0 {
188 blink = (inteltool.GPIO[GPO_BLINK] >> bit) & 1
189 } else {
190 blink = 0
192 irqset := lp_gpio_to_pirq(gpioNum)
193 if irqset >= 0 {
194 pirq = (inteltool.GPIO[GPIPIRQ2IOXAPIC] >> uint(irqset)) & 1
195 } else {
196 pirq = 0
199 if (conf0 & 1) == 0 {
200 fmt.Fprintf(gpio, "LP_GPIO_NATIVE,\n")
201 } else if (conf0 & 4) == 0 {
202 /* configured as output */
203 if ((conf0 >> 31) & 1) == 0 {
204 fmt.Fprintf(gpio, "LP_GPIO_OUT_LOW,\n")
205 } else {
206 fmt.Fprintf(gpio, "LP_GPIO_OUT_HIGH,\n")
208 } else if (conf1 & 4) != 0 {
209 /* configured as input and sensing disabled */
210 fmt.Fprintf(gpio, "LP_GPIO_UNUSED,\n")
211 } else {
212 is_preset := false
213 if conf1 == 0 && reset == 0 && blink == 0 {
214 preset := lpgpio_preset(conf0, owner, route, irqen, pirq)
215 if preset != "" {
216 fmt.Fprintf(gpio, "LP_%s,\n", preset)
217 is_preset = true
220 if !is_preset {
221 fmt.Fprintf(gpio, "{ %s },\n", gpio_str(conf0, conf1, owner, route, irqen, reset, blink, pirq))
227 func Lynxpoint_LP_GPIO(ctx Context, inteltool InteltoolData) {
228 gpio := Create(ctx, "gpio.c")
229 defer gpio.Close()
231 AddROMStageFile("gpio.c", "")
233 Add_gpl(gpio)
234 gpio.WriteString(`#include <southbridge/intel/lynxpoint/lp_gpio.h>
236 const struct pch_lp_gpio_map mainboard_lp_gpio_map[] = {
238 PrintLPGPIO(gpio, inteltool)
239 gpio.WriteString("\tLP_GPIO_END\n};\n")