lynxpoint_lp_gpio.go 5.2 KB

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