coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
gpio.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <soc/gpio.h>
5 #include <device/mmio.h>
6 #include <endian.h>
7 #include <soc/addressmap.h>
8 
9 union gpio_const {
10  u64 u;
11  struct {
12  u64 gpios:8; /** Number of GPIOs implemented */
13  u64 pp:8; /** Number of PP vectors */
14  u64:48; /* Reserved */
15  } s;
16 };
17 union bit_cfg {
18  u64 u;
19  struct {
20  u64 tx_oe : 1; /* Output Enable */
21  u64 xor : 1; /* Invert */
22  u64 int_en : 1; /* Interrupt Enable */
23  u64 int_type : 1; /* Type of Interrupt */
24  u64 filt_cnt : 4; /* Glitch filter counter */
25  u64 filt_sel : 4; /* Glitch filter select */
26  u64 tx_od : 1; /* Set Output to Open Drain */
27  u64 : 3;
28  u64 pin_sel : 10; /* Select type of pin */
29  u64 : 38;
30  } s;
31 };
32 
33 struct cavium_gpio {
41  union gpio_const gpio_const; /* Offset 90 */
42  u64 reserved2[109];
43  union bit_cfg bit_cfg[48]; /* Offset 400 */
44 };
45 
46 /* Base address of GPIO BAR */
47 static const void *gpio_get_baseaddr(void)
48 {
49  return (const void *)GPIO_PF_BAR0;
50 }
51 
52 /* Number of GPIO pins. Usually 48. */
54 {
55  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
56  union gpio_const gpio_const;
57 
58  gpio_const.u = read64(&regs->gpio_const.u);
59 
60  if (gpio_const.s.gpios > 64)
61  return 64; // FIXME: Add support for more than 64 GPIOs
62  return gpio_const.s.gpios;
63 }
64 
65 /* Set GPIO to software control and direction INPUT */
67 {
68  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
69  union bit_cfg bit_cfg;
70 
71  if (gpio >= gpio_pin_count())
72  return;
73 
74  printk(BIOS_SPEW, "GPIO(%u): direction input\n", gpio);
75 
76  bit_cfg.u = read64(&regs->bit_cfg[gpio]);
77  bit_cfg.s.pin_sel = 0;
78  bit_cfg.s.tx_oe = 0;
79  write64(&regs->bit_cfg[gpio], bit_cfg.u);
80 }
81 
82 /* Set GPIO of direction OUTPUT to level */
84 {
85  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
86 
87  if (gpio >= gpio_pin_count())
88  return;
89 
90  printk(BIOS_SPEW, "GPIO(%u): level: %u\n", gpio, !!value);
91 
92  if (value)
93  write64(&regs->tx_set, 1ULL << gpio);
94  else
95  write64(&regs->tx_clr, 1ULL << gpio);
96 }
97 
98 /* Set GPIO direction to OUTPUT with level */
100 {
101  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
102  union bit_cfg bit_cfg;
103 
104  if (gpio >= gpio_pin_count())
105  return;
106 
107  gpio_set(gpio, value);
108 
109  printk(BIOS_SPEW, "GPIO(%u): direction output with level: %u\n", gpio,
110  !!value);
111 
112  bit_cfg.u = read64(&regs->bit_cfg[gpio]);
113  bit_cfg.s.pin_sel = 0;
114  bit_cfg.s.tx_oe = 1;
115  write64(&regs->bit_cfg[gpio], bit_cfg.u);
116 }
117 
118 /* Set GPIO invert flag, that affects INPUT and OUTPUT */
120 {
121  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
122  union bit_cfg bit_cfg;
123 
124  if (gpio >= gpio_pin_count())
125  return;
126 
127  bit_cfg.u = read64(&regs->bit_cfg[gpio]);
128  bit_cfg.s.xor = !!value;
129  write64(&regs->bit_cfg[gpio], bit_cfg.u);
130 
131  printk(BIOS_SPEW, "GPIO(%u): invert: %s\n", gpio, value ? "ON" : "OFF");
132 }
133 
134 /* Read GPIO level with direction set to INPUT */
136 {
137  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
138 
139  if (gpio >= gpio_pin_count())
140  return 0;
141 
142  const u64 reg = read64(&regs->rx_dat);
143  printk(BIOS_SPEW, "GPIO(%u): input: %u\n", gpio,
144  !!(reg & (1ULL << gpio)));
145 
146  return !!(reg & (1ULL << gpio));
147 }
148 
149 /* Read GPIO STRAP level sampled at cold boot */
151 {
152  struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
153 
154  if (gpio >= gpio_pin_count())
155  return 0;
156 
157  const u64 reg = read64(&regs->strap);
158  printk(BIOS_SPEW, "GPIO(%u): strap: %u\n", gpio,
159  !!(reg & (1ULL << gpio)));
160 
161  return !!(reg & (1ULL << gpio));
162 }
163 
164 /* FIXME: Parse devicetree ? */
165 void gpio_init(void)
166 {
167  const size_t pin_count = gpio_pin_count();
168 
169  printk(BIOS_DEBUG, "GPIO: base address: %p, pin count: %zd\n",
170  gpio_get_baseaddr(), pin_count);
171 
172  if (!pin_count)
173  return;
174 }
175 
177 {
178 }
179 
181 {
182 }
pte_t value
Definition: mmu.c:91
void write64(void *addr, uint64_t val)
uint64_t read64(const void *addr)
#define printk(level,...)
Definition: stdlib.h:16
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
void gpio_set(gpio_t gpio_num, int value)
Definition: gpio.c:174
void gpio_output(gpio_t gpio_num, int value)
Definition: gpio.c:194
int gpio_get(gpio_t gpio_num)
Definition: gpio.c:166
void gpio_input_pullup(gpio_t gpio_num)
Definition: gpio.c:184
void gpio_input_pulldown(gpio_t gpio_num)
Definition: gpio.c:179
void gpio_input(gpio_t gpio_num)
Definition: gpio.c:189
int gpio_strap_value(gpio_t gpio)
Definition: gpio.c:150
static const void * gpio_get_baseaddr(void)
Definition: gpio.c:47
void gpio_invert(gpio_t gpio, int value)
Definition: gpio.c:119
gpio_t gpio_pin_count(void)
Definition: gpio.c:53
void gpio_init(void)
Definition: gpio.c:165
#define GPIO_PF_BAR0
Definition: addressmap.h:108
uint64_t u64
Definition: stdint.h:54
u64 strap
Definition: gpio.c:39
u64 rx_dat
Definition: gpio.c:34
u64 multicast
Definition: gpio.c:37
u64 tx_set
Definition: gpio.c:35
u64 tx_clr
Definition: gpio.c:36
u64 reserved2[109]
Definition: gpio.c:42
u64 ocla_exten_trg
Definition: gpio.c:38
u64 reserved[12]
Definition: gpio.c:40
Definition: pinmux.c:36
Definition: gpio.c:17
u64 filt_sel
Definition: gpio.c:25
u64 u
Definition: gpio.c:18
u64 int_type
Definition: gpio.c:23
u64 xor
Definition: gpio.c:21
u64 tx_od
Definition: gpio.c:26
u64 pin_sel
Definition: gpio.c:28
u64 tx_oe
Definition: gpio.c:20
u64 int_en
Definition: gpio.c:22
struct bit_cfg::@432 s
u64 filt_cnt
Definition: gpio.c:24
Definition: gpio.c:9
u64 u
Definition: gpio.c:10
struct gpio_const::@431 s
u64 gpios
Definition: gpio.c:12
u64 pp
Number of GPIOs implemented.
Definition: gpio.c:13