mb/google/nissa/var/rull: Add 6W and 15W DPTF parameters
[coreboot.git] / src / soc / cavium / cn81xx / gpio.c
blob4e29a572674f17681c07292abd23702881f7cdf8
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <soc/gpio.h>
5 #include <device/mmio.h>
6 #include <endian.h>
7 #include <soc/addressmap.h>
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;
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;
33 struct cavium_gpio {
34 u64 rx_dat;
35 u64 tx_set;
36 u64 tx_clr;
37 u64 multicast;
38 u64 ocla_exten_trg;
39 u64 strap;
40 u64 reserved[12];
41 union gpio_const gpio_const; /* Offset 90 */
42 u64 reserved2[109];
43 union bit_cfg bit_cfg[48]; /* Offset 400 */
46 /* Base address of GPIO BAR */
47 static const void *gpio_get_baseaddr(void)
49 return (const void *)GPIO_PF_BAR0;
52 /* Number of GPIO pins. Usually 48. */
53 gpio_t gpio_pin_count(void)
55 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
56 union gpio_const gpio_const;
58 gpio_const.u = read64(&regs->gpio_const.u);
60 if (gpio_const.s.gpios > 64)
61 return 64; // FIXME: Add support for more than 64 GPIOs
62 return gpio_const.s.gpios;
65 /* Set GPIO to software control and direction INPUT */
66 void gpio_input(gpio_t gpio)
68 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
69 union bit_cfg bit_cfg;
71 if (gpio >= gpio_pin_count())
72 return;
74 printk(BIOS_SPEW, "GPIO(%u): direction input\n", gpio);
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);
82 /* Set GPIO of direction OUTPUT to level */
83 void gpio_set(gpio_t gpio, int value)
85 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
87 if (gpio >= gpio_pin_count())
88 return;
90 printk(BIOS_SPEW, "GPIO(%u): level: %u\n", gpio, !!value);
92 if (value)
93 write64(&regs->tx_set, 1ULL << gpio);
94 else
95 write64(&regs->tx_clr, 1ULL << gpio);
98 /* Set GPIO direction to OUTPUT with level */
99 void gpio_output(gpio_t gpio, int value)
101 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
102 union bit_cfg bit_cfg;
104 if (gpio >= gpio_pin_count())
105 return;
107 gpio_set(gpio, value);
109 printk(BIOS_SPEW, "GPIO(%u): direction output with level: %u\n", gpio,
110 !!value);
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);
118 /* Set GPIO invert flag, that affects INPUT and OUTPUT */
119 void gpio_invert(gpio_t gpio, int value)
121 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
122 union bit_cfg bit_cfg;
124 if (gpio >= gpio_pin_count())
125 return;
127 bit_cfg.u = read64(&regs->bit_cfg[gpio]);
128 bit_cfg.s.xor = !!value;
129 write64(&regs->bit_cfg[gpio], bit_cfg.u);
131 printk(BIOS_SPEW, "GPIO(%u): invert: %s\n", gpio, value ? "ON" : "OFF");
134 /* Read GPIO level with direction set to INPUT */
135 int gpio_get(gpio_t gpio)
137 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
139 if (gpio >= gpio_pin_count())
140 return 0;
142 const u64 reg = read64(&regs->rx_dat);
143 printk(BIOS_SPEW, "GPIO(%u): input: %u\n", gpio,
144 !!(reg & (1ULL << gpio)));
146 return !!(reg & (1ULL << gpio));
149 /* Read GPIO STRAP level sampled at cold boot */
150 int gpio_strap_value(gpio_t gpio)
152 struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr();
154 if (gpio >= gpio_pin_count())
155 return 0;
157 const u64 reg = read64(&regs->strap);
158 printk(BIOS_SPEW, "GPIO(%u): strap: %u\n", gpio,
159 !!(reg & (1ULL << gpio)));
161 return !!(reg & (1ULL << gpio));
164 /* FIXME: Parse devicetree ? */
165 void gpio_init(void)
167 const size_t pin_count = gpio_pin_count();
169 printk(BIOS_DEBUG, "GPIO: base address: %p, pin count: %zd\n",
170 gpio_get_baseaddr(), pin_count);
172 if (!pin_count)
173 return;
176 void gpio_input_pulldown(gpio_t gpio)
180 void gpio_input_pullup(gpio_t gpio)