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 <stdint.h>
4 #include <arch/io.h>
5 #include <device/pci_ops.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 
9 #include "gpio.h"
10 
11 #define MAX_GPIO_NUMBER 75 /* zero based */
12 
13 /* LPC GPIO Base Address Register */
14 #define GPIO_BASE 0x48
15 
16 static u16 get_gpio_base(void)
17 {
18 #ifdef __SIMPLE_DEVICE__
19  /* Don't assume GPIO_BASE is still the same */
20  return pci_read_config16(PCI_DEV(0, 0x1f, 0), GPIO_BASE) & 0xfffe;
21 #else
22  static u16 gpiobase;
23 
24  if (gpiobase)
25  return gpiobase;
26 
27  gpiobase = pci_read_config16(pcidev_on_root(0x1f, 0), GPIO_BASE) & 0xfffe;
28 
29  return gpiobase;
30 #endif
31 }
32 
33 void setup_pch_gpios(const struct pch_gpio_map *gpio)
34 {
35  u16 gpiobase = get_gpio_base();
36 
37  /* The order of these calls does matter on ICH9M and prior.
38  * The level has to be set on pins configured as gpio,
39  * but on newer platforms we want to change the level first
40  * to make sure there are no glitches on the lines !
41  * Write the gpio level twice to satisfy both requirements.
42  */
43 
44  /* GPIO Set 1 */
45  if (gpio->set1.level)
46  outl(*((u32 *)gpio->set1.level), gpiobase + GP_LVL);
47  if (gpio->set1.mode)
48  outl(*((u32 *)gpio->set1.mode), gpiobase + GPIO_USE_SEL);
49  if (gpio->set1.direction)
50  outl(*((u32 *)gpio->set1.direction), gpiobase + GP_IO_SEL);
51  if (gpio->set1.level)
52  outl(*((u32 *)gpio->set1.level), gpiobase + GP_LVL);
53  if (gpio->set1.reset)
54  outl(*((u32 *)gpio->set1.reset), gpiobase + GP_RST_SEL1);
55  if (gpio->set1.invert)
56  outl(*((u32 *)gpio->set1.invert), gpiobase + GPI_INV);
57  if (gpio->set1.blink)
58  outl(*((u32 *)gpio->set1.blink), gpiobase + GPO_BLINK);
59 
60  /* GPIO Set 2 */
61  if (gpio->set2.level)
62  outl(*((u32 *)gpio->set2.level), gpiobase + GP_LVL2);
63  if (gpio->set2.mode)
64  outl(*((u32 *)gpio->set2.mode), gpiobase + GPIO_USE_SEL2);
65  if (gpio->set2.direction)
66  outl(*((u32 *)gpio->set2.direction), gpiobase + GP_IO_SEL2);
67  if (gpio->set2.level)
68  outl(*((u32 *)gpio->set2.level), gpiobase + GP_LVL2);
69  if (gpio->set2.reset)
70  outl(*((u32 *)gpio->set2.reset), gpiobase + GP_RST_SEL2);
71 
72  /* GPIO Set 3 */
73  if (gpio->set3.level)
74  outl(*((u32 *)gpio->set3.level), gpiobase + GP_LVL3);
75  if (gpio->set3.mode)
76  outl(*((u32 *)gpio->set3.mode), gpiobase + GPIO_USE_SEL3);
77  if (gpio->set3.direction)
78  outl(*((u32 *)gpio->set3.direction), gpiobase + GP_IO_SEL3);
79  if (gpio->set3.level)
80  outl(*((u32 *)gpio->set3.level), gpiobase + GP_LVL3);
81  if (gpio->set3.reset)
82  outl(*((u32 *)gpio->set3.reset), gpiobase + GP_RST_SEL3);
83 }
84 
85 /*
86  * return current gpio level.
87  */
88 int get_gpio(int gpio_num)
89 {
90  static const int gpio_reg_offsets[] = {GP_LVL, GP_LVL2, GP_LVL3};
91  u16 gpio_base = get_gpio_base();
92  int index, bit;
93 
94  if (gpio_num > MAX_GPIO_NUMBER)
95  return 0; /* Just ignore wrong gpio numbers. */
96 
97  index = gpio_num / 32;
98  bit = gpio_num % 32;
99 
100  return (inl(gpio_base + gpio_reg_offsets[index]) >> bit) & 1;
101 }
102 
103 /*
104  * get a number comprised of multiple GPIO values. gpio_num_array points to
105  * the array of gpio pin numbers to scan, terminated by -1.
106  */
107 unsigned int get_gpios(const int *gpio_num_array)
108 {
109  int gpio;
110  unsigned int bitmask = 1;
111  unsigned int vector = 0;
112 
113  while (bitmask &&
114  ((gpio = *gpio_num_array++) != -1)) {
115  if (get_gpio(gpio))
116  vector |= bitmask;
117  bitmask <<= 1;
118  }
119  return vector;
120 }
121 
122 /*
123  * set gpio output to level.
124  */
125 void set_gpio(int gpio_num, int value)
126 {
127  static const int gpio_reg_offsets[] = {
129  };
130  u16 gpio_base = get_gpio_base();
131  int index, bit;
132  u32 config;
133 
134  if (gpio_num > MAX_GPIO_NUMBER)
135  return; /* Just ignore wrong gpio numbers. */
136 
137  index = gpio_num / 32;
138  bit = gpio_num % 32;
139 
140  config = inl(gpio_base + gpio_reg_offsets[index]);
141  config &= ~(1 << bit);
142  if (value != 0)
143  config |= (1 << bit);
144  outl(config, gpio_base + gpio_reg_offsets[index]);
145 }
146 
147 int gpio_is_native(int gpio_num)
148 {
149  static const int gpio_reg_offsets[] = {
151  };
152  u16 gpio_base = get_gpio_base();
153  int index, bit;
154  u32 config;
155 
156  if (gpio_num > MAX_GPIO_NUMBER)
157  return 0; /* Just ignore wrong gpio numbers. */
158 
159  index = gpio_num / 32;
160  bit = gpio_num % 32;
161 
162  config = inl(gpio_base + gpio_reg_offsets[index]);
163  return !(config & (1 << bit));
164 }
pte_t value
Definition: mmu.c:91
u32 inl(u16 port)
void outl(u32 val, u16 port)
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
enum board_config config
Definition: memory.c:448
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
void setup_pch_gpios(const struct pch_gpio_map *gpio)
Definition: gpio.c:33
unsigned int get_gpios(const int *gpio_num_array)
Definition: gpio.c:107
int gpio_is_native(int gpio_num)
Definition: gpio.c:147
void set_gpio(int gpio_num, int value)
Definition: gpio.c:125
#define MAX_GPIO_NUMBER
Definition: gpio.c:11
static u16 get_gpio_base(void)
Definition: gpio.c:16
#define GPIO_BASE
Definition: gpio.c:14
int get_gpio(int gpio_num)
Definition: gpio.c:88
#define GPO_BLINK
Definition: gpio.h:12
#define GP_LVL
Definition: gpio.h:11
#define GP_IO_SEL
Definition: gpio.h:10
#define GP_LVL3
Definition: gpio.h:19
#define GP_RST_SEL3
Definition: gpio.h:22
#define GP_RST_SEL2
Definition: gpio.h:21
#define GPI_INV
Definition: gpio.h:13
#define GPIO_USE_SEL3
Definition: gpio.h:17
#define GP_RST_SEL1
Definition: gpio.h:20
#define GP_LVL2
Definition: gpio.h:16
#define GP_IO_SEL3
Definition: gpio.h:18
#define GPIO_USE_SEL
Definition: gpio.h:9
#define GPIO_USE_SEL2
Definition: gpio.h:14
#define GP_IO_SEL2
Definition: gpio.h:15
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
Definition: pinmux.c:36