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 <assert.h>
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <delay.h>
7 #include <soc/cpu.h>
8 #include <soc/gpio.h>
9 
10 #define CON_MASK(x) (0xf << ((x) << 2))
11 #define CON_SFR(x, v) ((v) << ((x) << 2))
12 
13 #define DAT_MASK(x) (0x1 << (x))
14 #define DAT_SET(x) (0x1 << (x))
15 
16 #define PULL_MASK(x) (0x3 << ((x) << 1))
17 #define PULL_MODE(x, v) ((v) << ((x) << 1))
18 
19 #define DRV_MASK(x) (0x3 << ((x) << 1))
20 #define DRV_SET(x, m) ((m) << ((x) << 1))
21 #define RATE_MASK(x) (0x1 << (x + 16))
22 #define RATE_SET(x) (0x1 << (x + 16))
23 
24 struct gpio_info {
25  unsigned int reg_addr; /* Address of register for this part */
26  unsigned int max_gpio; /* Maximum GPIO in this part */
27 };
28 
29 static const struct gpio_info gpio_data[EXYNOS_GPIO_NUM_PARTS] = {
36 };
37 
38 /* This macro gets gpio pin offset from 0..7 */
39 #define GPIO_BIT(x) ((x) & 0x7)
40 
41 static struct gpio_bank *gpio_get_bank(unsigned int gpio)
42 {
43  const struct gpio_info *data;
44  unsigned int upto;
45  int i;
46 
47  for (i = upto = 0, data = gpio_data; i < EXYNOS_GPIO_NUM_PARTS;
48  i++, upto = data->max_gpio, data++) {
50  struct gpio_bank *bank;
51 
52  bank = (struct gpio_bank *)data->reg_addr;
53  bank += (gpio - upto) / GPIO_PER_BANK;
54  return bank;
55  }
56  }
57 
58  ASSERT(gpio < GPIO_MAX_PORT); /* ...which it will not be */
59  return NULL;
60 }
61 
62 /* Common GPIO API - only available on Exynos5 */
63 void gpio_cfg_pin(int gpio, int cfg)
64 {
65  unsigned int value;
66  struct gpio_bank *bank = gpio_get_bank(gpio);
67 
68  value = read32(&bank->con);
70  value |= CON_SFR(GPIO_BIT(gpio), cfg);
71  write32(&bank->con, value);
72 }
73 
74 static int gpio_get_cfg(int gpio)
75 {
76  struct gpio_bank *bank = gpio_get_bank(gpio);
77  int shift = GPIO_BIT(gpio) << 2;
78 
79  return (read32(&bank->con) & CON_MASK(GPIO_BIT(gpio))) >> shift;
80 }
81 
82 void gpio_set_pull(int gpio, int mode)
83 {
84  unsigned int value;
85  struct gpio_bank *bank = gpio_get_bank(gpio);
86 
87  value = read32(&bank->pull);
89 
90  switch (mode) {
91  case GPIO_PULL_DOWN:
92  case GPIO_PULL_UP:
93  value |= PULL_MODE(GPIO_BIT(gpio), mode);
94  break;
95  default:
96  break;
97  }
98 
99  write32(&bank->pull, value);
100 }
101 
102 void gpio_set_drv(int gpio, int mode)
103 {
104  unsigned int value;
105  struct gpio_bank *bank = gpio_get_bank(gpio);
106 
107  value = read32(&bank->drv);
108  value &= ~DRV_MASK(GPIO_BIT(gpio));
109 
110  switch (mode) {
111  case GPIO_DRV_1X:
112  case GPIO_DRV_2X:
113  case GPIO_DRV_3X:
114  case GPIO_DRV_4X:
115  value |= DRV_SET(GPIO_BIT(gpio), mode);
116  break;
117  default:
118  return;
119  }
120 
121  write32(&bank->drv, value);
122 }
123 
124 void gpio_set_rate(int gpio, int mode)
125 {
126  unsigned int value;
127  struct gpio_bank *bank = gpio_get_bank(gpio);
128 
129  value = read32(&bank->drv);
131 
132  switch (mode) {
133  case GPIO_DRV_FAST:
134  case GPIO_DRV_SLOW:
136  break;
137  default:
138  return;
139  }
140 
141  write32(&bank->drv, value);
142 }
143 
144 int gpio_direction_input(unsigned int gpio)
145 {
147 
148  return 0;
149 }
150 
151 int gpio_direction_output(unsigned int gpio, int value)
152 {
153  unsigned int val;
154  struct gpio_bank *bank = gpio_get_bank(gpio);
155 
156  val = read32(&bank->dat);
157  val &= ~DAT_MASK(GPIO_BIT(gpio));
158  if (value)
159  val |= DAT_SET(GPIO_BIT(gpio));
160  write32(&bank->dat, val);
161 
163 
164  return 0;
165 }
166 
167 int gpio_get_value(unsigned int gpio)
168 {
169  unsigned int value;
170  struct gpio_bank *bank = gpio_get_bank(gpio);
171 
172  value = read32(&bank->dat);
173  return !!(value & DAT_MASK(GPIO_BIT(gpio)));
174 }
175 
176 int gpio_set_value(unsigned int gpio, int value)
177 {
178  unsigned int val;
179  struct gpio_bank *bank = gpio_get_bank(gpio);
180 
181  val = read32(&bank->dat);
182  val &= ~DAT_MASK(GPIO_BIT(gpio));
183  if (value)
184  val |= DAT_SET(GPIO_BIT(gpio));
185  write32(&bank->dat, val);
186 
187  return 0;
188 }
189 
190 /*
191  * Add a delay here to give the lines time to settle
192  * TODO(sjg): 1us does not always work, 2 is stable, so use 5 to be safe
193  * Come back to this and sort out what the datasheet says
194  */
195 #define GPIO_DELAY_US 5
196 
197 int gpio_read_mvl3(unsigned int gpio)
198 {
199  int high, low;
200  enum mvl3 value;
201 
202  if (gpio >= GPIO_MAX_PORT)
203  return -1;
204 
208  high = gpio_get_value(gpio);
211  low = gpio_get_value(gpio);
212 
213  if (high && low) /* external pullup */
214  value = LOGIC_1;
215  else if (!high && !low) /* external pulldown */
216  value = LOGIC_0;
217  else /* floating */
218  value = LOGIC_Z;
219 
220  /*
221  * Check if line is externally pulled high and
222  * configure the internal pullup to match. For
223  * floating and pulldowns, the GPIO is already
224  * configured with an internal pulldown from the
225  * above test.
226  */
227  if (value == LOGIC_1)
229 
230  return value;
231 }
232 
233 /*
234  * Display Exynos GPIO information
235  */
236 void gpio_info(void)
237 {
238  unsigned int gpio;
239 
240  for (gpio = 0; gpio < GPIO_MAX_PORT; gpio++) {
241  int cfg = gpio_get_cfg(gpio);
242 
243  printk(BIOS_INFO, "GPIO_%-3d: ", gpio);
244  if (cfg == GPIO_INPUT)
245  printk(BIOS_INFO, "input");
246  else if (cfg == GPIO_OUTPUT)
247  printk(BIOS_INFO, "output");
248  else
249  printk(BIOS_INFO, "func %d", cfg);
250 
251  if (cfg == GPIO_INPUT || cfg == GPIO_OUTPUT)
252  printk(BIOS_INFO, ", value = %d", gpio_get_value(gpio));
253  printk(BIOS_INFO, "\n");
254  }
255 }
#define GPIO_OUTPUT
Definition: gpio_ftns.h:23
#define GPIO_INPUT
Definition: gpio_ftns.h:24
pte_t value
Definition: mmu.c:91
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define ASSERT(x)
Definition: assert.h:44
#define printk(level,...)
Definition: stdlib.h:16
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
void gpio_set_pull(gpio_t gpio, enum pull_enable enable, enum pull_select select)
Definition: gpio.c:17
#define GPIO_PULL_UP
Definition: gpio.h:24
#define GPIO_PULL_DOWN
Definition: gpio.h:23
int gpio_read_mvl3(unsigned int gpio)
Definition: gpio.c:197
void gpio_cfg_pin(int gpio, int cfg)
Set GPIO pin configuration.
Definition: gpio.c:63
#define DRV_MASK(x)
Definition: gpio.c:19
#define PULL_MODE(x, v)
Definition: gpio.c:17
void gpio_set_rate(int gpio, int mode)
Set GPIO drive rate.
Definition: gpio.c:124
#define DAT_MASK(x)
Definition: gpio.c:13
#define DRV_SET(x, m)
Definition: gpio.c:20
#define RATE_MASK(x)
Definition: gpio.c:21
#define GPIO_DELAY_US
Definition: gpio.c:195
static struct gpio_bank * gpio_get_bank(unsigned int gpio)
Definition: gpio.c:41
#define PULL_MASK(x)
Definition: gpio.c:16
int gpio_direction_output(unsigned int gpio, int value)
Make a GPIO an output, and set its value.
Definition: gpio.c:151
static const struct gpio_info gpio_data[EXYNOS_GPIO_NUM_PARTS]
Definition: gpio.c:29
void gpio_info(void)
Definition: gpio.c:236
#define CON_MASK(x)
Definition: gpio.c:10
int gpio_direction_input(unsigned int gpio)
Make a GPIO an input.
Definition: gpio.c:144
#define CON_SFR(x, v)
Definition: gpio.c:11
int gpio_set_value(unsigned int gpio, int value)
Set an output GPIO's value.
Definition: gpio.c:176
static int gpio_get_cfg(int gpio)
Definition: gpio.c:74
int gpio_get_value(unsigned int gpio)
Get a GPIO's value.
Definition: gpio.c:167
void gpio_set_drv(int gpio, int mode)
Set GPIO drive strength level.
Definition: gpio.c:102
#define GPIO_BIT(x)
Definition: gpio.c:39
#define DAT_SET(x)
Definition: gpio.c:14
#define RATE_SET(x)
Definition: gpio.c:22
#define EXYNOS5_GPIO_PART3_BASE
Definition: cpu.h:44
#define EXYNOS5_GPIO_PART1_BASE
Definition: cpu.h:24
#define EXYNOS5_GPIO_PART6_BASE
Definition: cpu.h:10
#define EXYNOS5_GPIO_PART5_BASE
Definition: cpu.h:22
#define EXYNOS5_GPIO_PART2_BASE
Definition: cpu.h:25
#define EXYNOS5_GPIO_PART4_BASE
Definition: cpu.h:21
@ GPIO_MAX_PORT
Definition: gpio.h:430
@ GPIO_MAX_PORT_PART_4
Definition: gpio.h:411
@ GPIO_MAX_PORT_PART_2
Definition: gpio.h:301
@ GPIO_MAX_PORT_PART_3
Definition: gpio.h:376
@ GPIO_MAX_PORT_PART_5
Definition: gpio.h:422
@ GPIO_MAX_PORT_PART_1
Definition: gpio.h:266
#define GPIO_DRV_2X
Definition: gpio.h:37
mvl3
Definition: gpio.h:546
@ LOGIC_Z
Definition: gpio.h:549
@ LOGIC_0
Definition: gpio.h:547
@ LOGIC_1
Definition: gpio.h:548
#define GPIO_DRV_SLOW
Definition: gpio.h:40
#define GPIO_DRV_3X
Definition: gpio.h:36
#define GPIO_DRV_4X
Definition: gpio.h:38
#define GPIO_DRV_FAST
Definition: gpio.h:39
#define GPIO_PER_BANK
Definition: gpio.h:21
#define GPIO_DRV_1X
Definition: gpio.h:35
@ EXYNOS_GPIO_NUM_PARTS
Definition: gpio.h:98
#define NULL
Definition: stddef.h:19
unsigned int dat
Definition: gpio.h:12
unsigned int con
Definition: gpio.h:11
unsigned int pull
Definition: gpio.h:13
unsigned int drv
Definition: gpio.h:14
Definition: gpio.c:24
unsigned int max_gpio
Definition: gpio.c:26
unsigned int reg_addr
Definition: gpio.c:25
Definition: pinmux.c:36
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15