1 /*
2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <dm.h>
8 #include <malloc.h>
9 #include "irq-internal.h"
10
11 typedef enum GPIOIntType {
12 GPIOLevelLow = 0,
13 GPIOLevelHigh,
14 GPIOEdgelFalling,
15 GPIOEdgelRising
16 } eGPIOIntType_t;
17
18 typedef enum eGPIOPinLevel {
19 GPIO_LOW = 0,
20 GPIO_HIGH
21 } eGPIOPinLevel_t;
22
23 typedef enum eGPIOPinDirection {
24 GPIO_IN = 0,
25 GPIO_OUT
26 } eGPIOPinDirection_t;
27
28 #define GPIO_SWPORT_DR 0x00
29 #define GPIO_SWPORT_DDR 0x04
30 #define GPIO_INTEN 0x30
31 #define GPIO_INTMASK 0x34
32 #define GPIO_INTTYPE_LEVEL 0x38
33 #define GPIO_INT_POLARITY 0x3c
34 #define GPIO_INT_STATUS 0x40
35 #define GPIO_INT_RAWSTATUS 0x44
36 #define GPIO_DEBOUNCE 0x48
37 #define GPIO_PORTS_EOI 0x4c
38 #define GPIO_EXT_PORT 0x50
39 #define GPIO_LS_SYNC 0x60
40
pin_to_bit(unsigned pin)41 static inline unsigned pin_to_bit(unsigned pin)
42 {
43 return (1 << pin);
44 }
45
offset_to_bit(unsigned offset)46 static inline unsigned offset_to_bit(unsigned offset)
47 {
48 return (1 << offset);
49 }
50
gpio_bit_op(void __iomem * regbase,unsigned int offset,u32 bit,unsigned char flag)51 static void gpio_bit_op(void __iomem *regbase, unsigned int offset,
52 u32 bit, unsigned char flag)
53 {
54 u32 val = readl(regbase + offset);
55
56 if (flag)
57 val |= bit;
58 else
59 val &= ~bit;
60
61 writel(val, regbase + offset);
62 }
63
gpio_bit_rd(void __iomem * regbase,unsigned int offset,u32 bit)64 static int gpio_bit_rd(void __iomem *regbase, unsigned int offset, u32 bit)
65 {
66 return readl(regbase + offset) & bit ? 1 : 0;
67 }
68
gpio_irq_unmask(void __iomem * regbase,unsigned int bit)69 static void gpio_irq_unmask(void __iomem *regbase, unsigned int bit)
70 {
71 gpio_bit_op(regbase, GPIO_INTEN, bit, 1);
72 }
73
gpio_irq_mask(void __iomem * regbase,unsigned int bit)74 static void gpio_irq_mask(void __iomem *regbase, unsigned int bit)
75 {
76 gpio_bit_op(regbase, GPIO_INTEN, bit, 0);
77 }
78
gpio_irq_ack(void __iomem * regbase,unsigned int bit)79 static void gpio_irq_ack(void __iomem *regbase, unsigned int bit)
80 {
81 gpio_bit_op(regbase, GPIO_PORTS_EOI, bit, 1);
82 }
83
generic_gpio_handle_irq(int irq,void * data __always_unused)84 static void generic_gpio_handle_irq(int irq, void *data __always_unused)
85 {
86 struct gpio_bank *bank = gpio_id_to_bank(irq - IRQ_GPIO0);
87 unsigned gpio_irq, pin, unmasked = 0;
88 u32 isr, ilr;
89
90 isr = readl(bank->regbase + GPIO_INT_STATUS);
91 ilr = readl(bank->regbase + GPIO_INTTYPE_LEVEL);
92
93 gpio_irq = bank->irq_base;
94
95 while (isr) {
96 pin = fls(isr) - 1;
97
98 /* first mask and ack irq */
99 gpio_irq_mask(bank->regbase, offset_to_bit(pin));
100 gpio_irq_ack(bank->regbase, offset_to_bit(pin));
101
102 /*
103 * If gpio is edge triggered, clear condition before executing
104 * the handler, so that we don't miss next edges trigger.
105 */
106 if (ilr & (1 << pin)) {
107 unmasked = 1;
108 gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
109 }
110
111 __generic_gpio_handle_irq(gpio_irq + pin);
112
113 isr &= ~(1 << pin);
114
115 if (!unmasked)
116 gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
117 }
118 }
119
gpio_set_intr_type(void __iomem * regbase,unsigned int bit,eGPIOIntType_t type)120 static void gpio_set_intr_type(void __iomem *regbase,
121 unsigned int bit,
122 eGPIOIntType_t type)
123 {
124 switch (type) {
125 case GPIOLevelLow:
126 gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
127 gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
128 break;
129 case GPIOLevelHigh:
130 gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
131 gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
132 break;
133 case GPIOEdgelFalling:
134 gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
135 gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
136 break;
137 case GPIOEdgelRising:
138 gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
139 gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
140 break;
141 }
142 }
143
gpio_get_intr_type(void __iomem * regbase,unsigned int bit)144 static int gpio_get_intr_type(void __iomem *regbase,
145 unsigned int bit)
146 {
147 u32 polarity, level, magic = 0;
148 int type;
149
150 polarity = gpio_bit_rd(regbase, GPIO_INT_POLARITY, bit);
151 level = gpio_bit_rd(regbase, GPIO_INTTYPE_LEVEL, bit);
152 magic = (polarity << 1) | (level << 0);
153
154 switch (magic) {
155 case 0x00:
156 type = GPIOLevelLow;
157 break;
158 case 0x02:
159 type = GPIOLevelHigh;
160 break;
161 case 0x01:
162 type = GPIOEdgelFalling;
163 break;
164 case 0x03:
165 type = GPIOEdgelRising;
166 break;
167 default:
168 type = -EINVAL;
169 }
170
171 return type;
172 }
173
gpio_irq_set_type(int gpio_irq,unsigned int type)174 static int gpio_irq_set_type(int gpio_irq, unsigned int type)
175 {
176 int gpio = irq_to_gpio(gpio_irq);
177 struct gpio_bank *bank = gpio_to_bank(gpio);
178 eGPIOIntType_t int_type = 0;
179
180 if (!bank)
181 return -EINVAL;
182
183 gpio &= GPIO_PIN_MASK;
184 if (gpio >= bank->ngpio)
185 return -EINVAL;
186
187 switch (type) {
188 case IRQ_TYPE_EDGE_RISING:
189 int_type = GPIOEdgelRising;
190 break;
191 case IRQ_TYPE_EDGE_FALLING:
192 int_type = GPIOEdgelFalling;
193 break;
194 case IRQ_TYPE_LEVEL_HIGH:
195 int_type = GPIOLevelHigh;
196 break;
197 case IRQ_TYPE_LEVEL_LOW:
198 int_type = GPIOLevelLow;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 /* Before set interrupt type, gpio must set input */
205 gpio_bit_op(bank->regbase, GPIO_SWPORT_DDR,
206 offset_to_bit(gpio), GPIO_IN);
207 gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
208
209 return 0;
210 }
211
gpio_irq_revert_type(int gpio_irq)212 static int gpio_irq_revert_type(int gpio_irq)
213 {
214 int gpio = irq_to_gpio(gpio_irq);
215 struct gpio_bank *bank = gpio_to_bank(gpio);
216 eGPIOIntType_t int_type = 0;
217 int type;
218
219 if (!bank)
220 return -EINVAL;
221
222 gpio &= GPIO_PIN_MASK;
223 if (gpio >= bank->ngpio)
224 return -EINVAL;
225
226 type = gpio_get_intr_type(bank->regbase, offset_to_bit(gpio));
227 switch (type) {
228 case GPIOEdgelFalling:
229 int_type = GPIOEdgelRising;
230 break;
231 case GPIOEdgelRising:
232 int_type = GPIOEdgelFalling;
233 break;
234 case GPIOLevelHigh:
235 int_type = GPIOLevelLow;
236 break;
237 case GPIOLevelLow:
238 int_type = GPIOLevelHigh;
239 break;
240 default:
241 return -EINVAL;
242 }
243
244 gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
245
246 return 0;
247 }
248
gpio_irq_get_gpio_level(int gpio_irq)249 static int gpio_irq_get_gpio_level(int gpio_irq)
250 {
251 int gpio = irq_to_gpio(gpio_irq);
252 struct gpio_bank *bank = gpio_to_bank(gpio);
253
254 if (!bank)
255 return -EINVAL;
256
257 gpio &= GPIO_PIN_MASK;
258 if (gpio >= bank->ngpio)
259 return -EINVAL;
260
261 return gpio_bit_rd(bank->regbase, GPIO_EXT_PORT, offset_to_bit(gpio));
262 }
263
gpio_irq_enable(int gpio_irq)264 static int gpio_irq_enable(int gpio_irq)
265 {
266 int gpio = irq_to_gpio(gpio_irq);
267 struct gpio_bank *bank = gpio_to_bank(gpio);
268
269 if (!bank)
270 return -EINVAL;
271
272 gpio &= GPIO_PIN_MASK;
273 if (gpio >= bank->ngpio)
274 return -EINVAL;
275
276 gpio_irq_unmask(bank->regbase, offset_to_bit(gpio));
277
278 if (bank->use_count == 0)
279 irq_handler_enable(IRQ_GPIO0 + bank->id);
280 bank->use_count++;
281
282 return 0;
283 }
284
gpio_irq_disable(int irq)285 static int gpio_irq_disable(int irq)
286 {
287 int gpio = irq_to_gpio(irq);
288 struct gpio_bank *bank = gpio_to_bank(gpio);
289
290 if (!bank)
291 return -EINVAL;
292
293 if (bank->use_count <= 0)
294 return 0;
295
296 gpio &= GPIO_PIN_MASK;
297 if (gpio >= bank->ngpio)
298 return -EINVAL;
299
300 gpio_irq_mask(bank->regbase, offset_to_bit(gpio));
301
302 if (bank->use_count == 1)
303 irq_handler_disable(IRQ_GPIO0 + bank->id);
304 bank->use_count--;
305
306 return 0;
307 }
308
gpio_irq_init(void)309 static int gpio_irq_init(void)
310 {
311 struct gpio_bank *bank = NULL;
312 int i = 0;
313
314 for (i = 0; i < GPIO_BANK_NUM; i++) {
315 struct udevice *dev;
316
317 dev = malloc(sizeof(*dev));
318 if (!dev)
319 return -ENOMEM;
320
321 bank = gpio_id_to_bank(i);
322 if (bank) {
323 dev->name = bank->name;
324
325 /* disable gpio pin interrupt */
326 writel(0, bank->regbase + GPIO_INTEN);
327
328 /* register gpio group irq handler */
329 irq_install_handler(IRQ_GPIO0 + bank->id,
330 (interrupt_handler_t *)generic_gpio_handle_irq, dev);
331
332 /* default disable all gpio group interrupt */
333 irq_handler_disable(IRQ_GPIO0 + bank->id);
334 }
335 }
336
337 return 0;
338 }
339
340 static struct irq_chip gpio_irq_chip = {
341 .name = "gpio-irq-chip",
342 .irq_init = gpio_irq_init,
343 .irq_enable = gpio_irq_enable,
344 .irq_disable = gpio_irq_disable,
345 .irq_set_type = gpio_irq_set_type,
346 .irq_revert_type = gpio_irq_revert_type,
347 .irq_get_gpio_level = gpio_irq_get_gpio_level,
348 };
349
arch_gpio_get_irqchip(void)350 struct irq_chip *arch_gpio_get_irqchip(void)
351 {
352 return &gpio_irq_chip;
353 }
354