xref: /rk3399_rockchip-uboot/drivers/irq/irq-gpio.c (revision 5821df21ae36d9ef252d346a5abb76be773c5d69)
1 /*
2  * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <asm/io.h>
8 #include <irq-generic.h>
9 #include "irq-gpio.h"
10 #include "irq-gpio-switch.h"
11 
12 typedef enum GPIOIntType {
13 	GPIOLevelLow = 0,
14 	GPIOLevelHigh,
15 	GPIOEdgelFalling,
16 	GPIOEdgelRising
17 } eGPIOIntType_t;
18 
19 typedef enum eGPIOPinLevel {
20 	GPIO_LOW = 0,
21 	GPIO_HIGH
22 } eGPIOPinLevel_t;
23 
24 typedef enum eGPIOPinDirection {
25 	GPIO_IN = 0,
26 	GPIO_OUT
27 } eGPIOPinDirection_t;
28 
29 #define GPIO_SWPORT_DR		0x00
30 #define GPIO_SWPORT_DDR		0x04
31 #define GPIO_INTEN		0x30
32 #define GPIO_INTMASK		0x34
33 #define GPIO_INTTYPE_LEVEL	0x38
34 #define GPIO_INT_POLARITY	0x3c
35 #define GPIO_INT_STATUS		0x40
36 #define GPIO_INT_RAWSTATUS	0x44
37 #define GPIO_DEBOUNCE		0x48
38 #define GPIO_PORTS_EOI		0x4c
39 #define GPIO_EXT_PORT		0x50
40 #define GPIO_LS_SYNC		0x60
41 
42 static inline unsigned pin_to_bit(unsigned pin)
43 {
44 	return (1 << pin);
45 }
46 
47 static inline unsigned offset_to_bit(unsigned offset)
48 {
49 	return (1 << offset);
50 }
51 
52 static void gpio_bit_op(void __iomem *regbase, unsigned int offset,
53 			u32 bit, unsigned char flag)
54 {
55 	u32 val = readl(regbase + offset);
56 
57 	if (flag)
58 		val |= bit;
59 	else
60 		val &= ~bit;
61 
62 	writel(val, regbase + offset);
63 }
64 
65 static void gpio_irq_unmask(void __iomem *regbase, unsigned int bit)
66 {
67 	gpio_bit_op(regbase, GPIO_INTEN, bit, 1);
68 }
69 
70 static void gpio_irq_mask(void __iomem *regbase, unsigned int bit)
71 {
72 	gpio_bit_op(regbase, GPIO_INTEN, bit, 0);
73 }
74 
75 static void gpio_irq_ack(void __iomem *regbase, unsigned int bit)
76 {
77 	gpio_bit_op(regbase, GPIO_PORTS_EOI, bit, 1);
78 }
79 
80 static void generic_gpio_handle_irq(int irq, void *data __always_unused)
81 {
82 	struct gpio_bank *bank = gpio_id_to_bank(irq - IRQ_GPIO0);
83 	unsigned gpio_irq, pin, unmasked = 0;
84 	u32 isr, ilr;
85 
86 	isr = readl(bank->regbase + GPIO_INT_STATUS);
87 	ilr = readl(bank->regbase + GPIO_INTTYPE_LEVEL);
88 
89 	gpio_irq = bank->irq_base;
90 
91 	while (isr) {
92 		pin = fls(isr) - 1;
93 
94 		/* first mask and ack irq */
95 		gpio_irq_mask(bank->regbase, offset_to_bit(pin));
96 		gpio_irq_ack(bank->regbase, offset_to_bit(pin));
97 
98 		/*
99 		 * if gpio is edge triggered, clear condition before executing
100 		 * the handler so that we don't miss edges
101 		 */
102 		if (ilr & (1 << pin)) {
103 			unmasked = 1;
104 			gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
105 		}
106 
107 		_generic_gpio_handle_irq(gpio_irq + pin);
108 
109 		isr &= ~(1 << pin);
110 
111 		if (!unmasked)
112 			gpio_irq_unmask(bank->regbase, offset_to_bit(pin));
113 	}
114 }
115 
116 static void gpio_set_intr_type(void __iomem *regbase,
117 			       unsigned int bit,
118 			       eGPIOIntType_t type)
119 {
120 	switch (type) {
121 	case GPIOLevelLow:
122 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
123 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
124 		break;
125 	case GPIOLevelHigh:
126 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 0);
127 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
128 		break;
129 	case GPIOEdgelFalling:
130 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
131 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 0);
132 		break;
133 	case GPIOEdgelRising:
134 		gpio_bit_op(regbase, GPIO_INTTYPE_LEVEL, bit, 1);
135 		gpio_bit_op(regbase, GPIO_INT_POLARITY, bit, 1);
136 		break;
137 	}
138 }
139 
140 static int gpio_irq_set_type(int gpio_irq, unsigned int type)
141 {
142 	int gpio = irq_to_gpio(gpio_irq);
143 	struct gpio_bank *bank = gpio_to_bank(gpio);
144 	eGPIOIntType_t int_type = 0;
145 
146 	if (!bank)
147 		return -EINVAL;
148 
149 	gpio &= GPIO_PIN_MASK;
150 	if (gpio >= bank->ngpio)
151 		return -EINVAL;
152 
153 	switch (type) {
154 	case IRQ_TYPE_EDGE_RISING:
155 		int_type = GPIOEdgelRising;
156 		break;
157 	case IRQ_TYPE_EDGE_FALLING:
158 		int_type = GPIOEdgelFalling;
159 		break;
160 	case IRQ_TYPE_LEVEL_HIGH:
161 		int_type = GPIOLevelHigh;
162 		break;
163 	case IRQ_TYPE_LEVEL_LOW:
164 		int_type = GPIOLevelLow;
165 		break;
166 	default:
167 		return -EINVAL;
168 	}
169 
170 	/* Before set interrupt type, gpio must set input */
171 	gpio_bit_op(bank->regbase, GPIO_SWPORT_DDR,
172 		    offset_to_bit(gpio), GPIO_IN);
173 	gpio_set_intr_type(bank->regbase, offset_to_bit(gpio), int_type);
174 
175 	return 0;
176 }
177 
178 static int gpio_irq_enable(int gpio_irq)
179 {
180 	int gpio = irq_to_gpio(gpio_irq);
181 	struct gpio_bank *bank = gpio_to_bank(gpio);
182 
183 	if (!bank)
184 		return -EINVAL;
185 
186 	gpio &= GPIO_PIN_MASK;
187 	if (gpio >= bank->ngpio)
188 		return -EINVAL;
189 
190 	gpio_irq_unmask(bank->regbase, offset_to_bit(gpio));
191 
192 	return 0;
193 }
194 
195 static int gpio_irq_disable(int irq)
196 {
197 	int gpio = irq_to_gpio(irq);
198 	struct gpio_bank *bank = gpio_to_bank(gpio);
199 
200 	if (!bank)
201 		return -EINVAL;
202 
203 	gpio &= GPIO_PIN_MASK;
204 	if (gpio >= bank->ngpio)
205 		return -EINVAL;
206 
207 	gpio_irq_mask(bank->regbase, offset_to_bit(gpio));
208 
209 	return 0;
210 }
211 
212 static int gpio_irq_init(void)
213 {
214 	struct gpio_bank *bank = NULL;
215 	int i = 0;
216 
217 	for (i = 0; i < GPIO_BANK_NUM; i++) {
218 		bank = gpio_id_to_bank(i);
219 		if (bank) {
220 			/* disable gpio pin interrupt */
221 			writel(0, bank->regbase + GPIO_INTEN);
222 
223 			/* register gpio group irq handler */
224 			irq_install_handler(IRQ_GPIO0 + bank->id,
225 			(interrupt_handler_t *)generic_gpio_handle_irq, NULL);
226 
227 			/* default enable all gpio group interrupt */
228 			irq_handler_enable(IRQ_GPIO0 + bank->id);
229 		}
230 	}
231 
232 	return 0;
233 }
234 
235 static struct irq_chip gpio_irq_chip = {
236 	.name		= "gpio-irq-chip",
237 	.irq_init	= gpio_irq_init,
238 	.irq_enable	= gpio_irq_enable,
239 	.irq_disable	= gpio_irq_disable,
240 	.irq_set_type	= gpio_irq_set_type,
241 };
242 
243 struct irq_chip *arch_gpio_irq_init(void)
244 {
245 	return &gpio_irq_chip;
246 }
247