blob: 6fdb7c1bbcdf082fbf84209430472fc96c18f3ad [file] [log] [blame]
Angel Pons1ddb8942020-04-04 18:51:26 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Gabe Black607c0b62013-05-16 05:45:57 -07002
Gabe Black607c0b62013-05-16 05:45:57 -07003#include <assert.h>
Julius Werner80af4422014-10-20 13:18:56 -07004#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Julius Werner80af4422014-10-20 13:18:56 -07006#include <delay.h>
7#include <soc/cpu.h>
8#include <soc/gpio.h>
Gabe Black607c0b62013-05-16 05:45:57 -07009
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
24struct 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
29static const struct gpio_info gpio_data[EXYNOS_GPIO_NUM_PARTS] = {
Julius Wernerfa938c72013-08-29 14:17:36 -070030 { EXYNOS5420_GPIO_PART1_BASE, GPIO_MAX_PORT_PART_1 },
31 { EXYNOS5420_GPIO_PART2_BASE, GPIO_MAX_PORT_PART_2 },
32 { EXYNOS5420_GPIO_PART3_BASE, GPIO_MAX_PORT_PART_3 },
33 { EXYNOS5420_GPIO_PART4_BASE, GPIO_MAX_PORT_PART_4 },
34 { EXYNOS5420_GPIO_PART5_BASE, GPIO_MAX_PORT_PART_5 },
35 { EXYNOS5420_GPIO_PART6_BASE, GPIO_MAX_PORT },
Gabe Black607c0b62013-05-16 05:45:57 -070036};
37
38/* This macro gets gpio pin offset from 0..7 */
39#define GPIO_BIT(x) ((x) & 0x7)
40
41static 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++) {
49 if (gpio < data->max_gpio) {
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 */
63void gpio_cfg_pin(int gpio, int cfg)
64{
65 unsigned int value;
66 struct gpio_bank *bank = gpio_get_bank(gpio);
67
Julius Werner2f37bd62015-02-19 14:51:15 -080068 value = read32(&bank->con);
Gabe Black607c0b62013-05-16 05:45:57 -070069 value &= ~CON_MASK(GPIO_BIT(gpio));
70 value |= CON_SFR(GPIO_BIT(gpio), cfg);
Julius Werner2f37bd62015-02-19 14:51:15 -080071 write32(&bank->con, value);
Gabe Black607c0b62013-05-16 05:45:57 -070072}
73
74static int gpio_get_cfg(int gpio)
75{
76 struct gpio_bank *bank = gpio_get_bank(gpio);
77 int shift = GPIO_BIT(gpio) << 2;
78
Julius Werner2f37bd62015-02-19 14:51:15 -080079 return (read32(&bank->con) & CON_MASK(GPIO_BIT(gpio))) >> shift;
Gabe Black607c0b62013-05-16 05:45:57 -070080}
81
82void gpio_set_pull(int gpio, int mode)
83{
84 unsigned int value;
85 struct gpio_bank *bank = gpio_get_bank(gpio);
86
Julius Werner2f37bd62015-02-19 14:51:15 -080087 value = read32(&bank->pull);
Gabe Black607c0b62013-05-16 05:45:57 -070088 value &= ~PULL_MASK(GPIO_BIT(gpio));
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
Julius Werner2f37bd62015-02-19 14:51:15 -080099 write32(&bank->pull, value);
Gabe Black607c0b62013-05-16 05:45:57 -0700100}
101
102void gpio_set_drv(int gpio, int mode)
103{
104 unsigned int value;
105 struct gpio_bank *bank = gpio_get_bank(gpio);
106
Julius Werner2f37bd62015-02-19 14:51:15 -0800107 value = read32(&bank->drv);
Gabe Black607c0b62013-05-16 05:45:57 -0700108 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
Julius Werner2f37bd62015-02-19 14:51:15 -0800121 write32(&bank->drv, value);
Gabe Black607c0b62013-05-16 05:45:57 -0700122}
123
124void gpio_set_rate(int gpio, int mode)
125{
126 unsigned int value;
127 struct gpio_bank *bank = gpio_get_bank(gpio);
128
Julius Werner2f37bd62015-02-19 14:51:15 -0800129 value = read32(&bank->drv);
Gabe Black607c0b62013-05-16 05:45:57 -0700130 value &= ~RATE_MASK(GPIO_BIT(gpio));
131
132 switch (mode) {
133 case GPIO_DRV_FAST:
134 case GPIO_DRV_SLOW:
135 value |= RATE_SET(GPIO_BIT(gpio));
136 break;
137 default:
138 return;
139 }
140
Julius Werner2f37bd62015-02-19 14:51:15 -0800141 write32(&bank->drv, value);
Gabe Black607c0b62013-05-16 05:45:57 -0700142}
143
Martin Roth57e89092019-10-23 21:45:23 -0600144int gpio_direction_input(unsigned int gpio)
Gabe Black607c0b62013-05-16 05:45:57 -0700145{
146 gpio_cfg_pin(gpio, GPIO_INPUT);
147
148 return 0;
149}
150
Martin Roth57e89092019-10-23 21:45:23 -0600151int gpio_direction_output(unsigned int gpio, int value)
Gabe Black607c0b62013-05-16 05:45:57 -0700152{
153 unsigned int val;
154 struct gpio_bank *bank = gpio_get_bank(gpio);
155
Julius Werner2f37bd62015-02-19 14:51:15 -0800156 val = read32(&bank->dat);
Gabe Black607c0b62013-05-16 05:45:57 -0700157 val &= ~DAT_MASK(GPIO_BIT(gpio));
158 if (value)
159 val |= DAT_SET(GPIO_BIT(gpio));
Julius Werner2f37bd62015-02-19 14:51:15 -0800160 write32(&bank->dat, val);
Gabe Black607c0b62013-05-16 05:45:57 -0700161
Ronald G. Minnich32450562013-06-18 13:02:23 -0700162 gpio_cfg_pin(gpio, GPIO_OUTPUT);
163
Gabe Black607c0b62013-05-16 05:45:57 -0700164 return 0;
165}
166
Martin Roth57e89092019-10-23 21:45:23 -0600167int gpio_get_value(unsigned int gpio)
Gabe Black607c0b62013-05-16 05:45:57 -0700168{
169 unsigned int value;
170 struct gpio_bank *bank = gpio_get_bank(gpio);
171
Julius Werner2f37bd62015-02-19 14:51:15 -0800172 value = read32(&bank->dat);
Gabe Black607c0b62013-05-16 05:45:57 -0700173 return !!(value & DAT_MASK(GPIO_BIT(gpio)));
174}
175
Martin Roth57e89092019-10-23 21:45:23 -0600176int gpio_set_value(unsigned int gpio, int value)
Gabe Black607c0b62013-05-16 05:45:57 -0700177{
178 unsigned int val;
179 struct gpio_bank *bank = gpio_get_bank(gpio);
180
Julius Werner2f37bd62015-02-19 14:51:15 -0800181 val = read32(&bank->dat);
Gabe Black607c0b62013-05-16 05:45:57 -0700182 val &= ~DAT_MASK(GPIO_BIT(gpio));
183 if (value)
184 val |= DAT_SET(GPIO_BIT(gpio));
Julius Werner2f37bd62015-02-19 14:51:15 -0800185 write32(&bank->dat, val);
Gabe Black607c0b62013-05-16 05:45:57 -0700186
187 return 0;
188}
189
190/*
191 * Add a delay here to give the lines time to settle
David Hendricksb7743132013-08-09 18:19:29 -0700192 * TODO(dianders): 5us does not always work, 10 is stable, so use 15 to be safe
Gabe Black607c0b62013-05-16 05:45:57 -0700193 * Come back to this and sort out what the datasheet says
194 */
David Hendricksb7743132013-08-09 18:19:29 -0700195#define GPIO_DELAY_US 15
Gabe Black607c0b62013-05-16 05:45:57 -0700196
Martin Roth57e89092019-10-23 21:45:23 -0600197int gpio_read_mvl3(unsigned int gpio)
Gabe Black607c0b62013-05-16 05:45:57 -0700198{
199 int high, low;
200 enum mvl3 value;
201
202 if (gpio >= GPIO_MAX_PORT)
203 return -1;
204
205 gpio_direction_input(gpio);
206 gpio_set_pull(gpio, GPIO_PULL_UP);
207 udelay(GPIO_DELAY_US);
208 high = gpio_get_value(gpio);
209 gpio_set_pull(gpio, GPIO_PULL_DOWN);
210 udelay(GPIO_DELAY_US);
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)
228 gpio_set_pull(gpio, GPIO_PULL_UP);
229
230 return value;
231}
Gabe Black607c0b62013-05-16 05:45:57 -0700232
233/*
234 * Display Exynos GPIO information
235 */
236void gpio_info(void)
237{
Martin Roth57e89092019-10-23 21:45:23 -0600238 unsigned int gpio;
Gabe Black607c0b62013-05-16 05:45:57 -0700239
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}