1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <device/mmio.h>
7 #include <soc/addressmap.h>
12 u64 gpios
:8; /** Number of GPIOs implemented */
13 u64 pp
:8; /** Number of PP vectors */
14 u64
:48; /* Reserved */
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 */
28 u64 pin_sel
: 10; /* Select type of pin */
41 union gpio_const gpio_const
; /* Offset 90 */
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(®s
->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())
74 printk(BIOS_SPEW
, "GPIO(%u): direction input\n", gpio
);
76 bit_cfg
.u
= read64(®s
->bit_cfg
[gpio
]);
77 bit_cfg
.s
.pin_sel
= 0;
79 write64(®s
->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())
90 printk(BIOS_SPEW
, "GPIO(%u): level: %u\n", gpio
, !!value
);
93 write64(®s
->tx_set
, 1ULL << gpio
);
95 write64(®s
->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())
107 gpio_set(gpio
, value
);
109 printk(BIOS_SPEW
, "GPIO(%u): direction output with level: %u\n", gpio
,
112 bit_cfg
.u
= read64(®s
->bit_cfg
[gpio
]);
113 bit_cfg
.s
.pin_sel
= 0;
115 write64(®s
->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())
127 bit_cfg
.u
= read64(®s
->bit_cfg
[gpio
]);
128 bit_cfg
.s
.xor = !!value
;
129 write64(®s
->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())
142 const u64 reg
= read64(®s
->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())
157 const u64 reg
= read64(®s
->strap
);
158 printk(BIOS_SPEW
, "GPIO(%u): strap: %u\n", gpio
,
159 !!(reg
& (1ULL << gpio
)));
161 return !!(reg
& (1ULL << gpio
));
164 /* FIXME: Parse devicetree ? */
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
);
176 void gpio_input_pulldown(gpio_t gpio
)
180 void gpio_input_pullup(gpio_t gpio
)