xref: /rk3399_ARM-atf/plat/mediatek/mt8192/drivers/gpio/mtgpio.c (revision 054af8f233d94670dca1a27992296a5afc6b1f73)
1*054af8f2SPo Xu /*
2*054af8f2SPo Xu  * Copyright (c) 2020, MediaTek Inc. All rights reserved.
3*054af8f2SPo Xu  *
4*054af8f2SPo Xu  * SPDX-License-Identifier: BSD-3-Clause
5*054af8f2SPo Xu  */
6*054af8f2SPo Xu 
7*054af8f2SPo Xu #include <assert.h>
8*054af8f2SPo Xu #include <common/debug.h>
9*054af8f2SPo Xu #include <drivers/delay_timer.h>
10*054af8f2SPo Xu #include <drivers/gpio.h>
11*054af8f2SPo Xu #include <lib/mmio.h>
12*054af8f2SPo Xu #include <mtgpio.h>
13*054af8f2SPo Xu #include <platform_def.h>
14*054af8f2SPo Xu 
15*054af8f2SPo Xu /******************************************************************************
16*054af8f2SPo Xu  *Macro Definition
17*054af8f2SPo Xu  ******************************************************************************/
18*054af8f2SPo Xu #define GPIO_MODE_BITS		4
19*054af8f2SPo Xu #define MAX_GPIO_MODE_PER_REG	8
20*054af8f2SPo Xu #define MAX_GPIO_REG_BITS	32
21*054af8f2SPo Xu #define DIR_BASE		(GPIO_BASE + 0x000)
22*054af8f2SPo Xu #define DOUT_BASE		(GPIO_BASE + 0x100)
23*054af8f2SPo Xu #define DIN_BASE		(GPIO_BASE + 0x200)
24*054af8f2SPo Xu #define MODE_BASE		(GPIO_BASE + 0x300)
25*054af8f2SPo Xu #define SET			0x4
26*054af8f2SPo Xu #define CLR			0x8
27*054af8f2SPo Xu 
28*054af8f2SPo Xu static void mt_set_gpio_dir_chip(uint32_t pin, int dir)
29*054af8f2SPo Xu {
30*054af8f2SPo Xu 	uint32_t pos, bit;
31*054af8f2SPo Xu 
32*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
33*054af8f2SPo Xu 	assert(dir < MT_GPIO_DIR_MAX);
34*054af8f2SPo Xu 
35*054af8f2SPo Xu 	pos = pin / MAX_GPIO_REG_BITS;
36*054af8f2SPo Xu 	bit = pin % MAX_GPIO_REG_BITS;
37*054af8f2SPo Xu 
38*054af8f2SPo Xu 	if (dir == MT_GPIO_DIR_IN) {
39*054af8f2SPo Xu 		mmio_write_32(DIR_BASE + 0x10U * pos + CLR, 1U << bit);
40*054af8f2SPo Xu 	} else {
41*054af8f2SPo Xu 		mmio_write_32(DIR_BASE + 0x10U * pos + SET, 1U << bit);
42*054af8f2SPo Xu 	}
43*054af8f2SPo Xu }
44*054af8f2SPo Xu 
45*054af8f2SPo Xu static int mt_get_gpio_dir_chip(uint32_t pin)
46*054af8f2SPo Xu {
47*054af8f2SPo Xu 	uint32_t pos, bit;
48*054af8f2SPo Xu 	uint32_t reg;
49*054af8f2SPo Xu 
50*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
51*054af8f2SPo Xu 
52*054af8f2SPo Xu 	pos = pin / MAX_GPIO_REG_BITS;
53*054af8f2SPo Xu 	bit = pin % MAX_GPIO_REG_BITS;
54*054af8f2SPo Xu 
55*054af8f2SPo Xu 	reg = mmio_read_32(DIR_BASE + 0x10U * pos);
56*054af8f2SPo Xu 	return (((reg & (1U << bit)) != 0U) ? MT_GPIO_DIR_OUT : MT_GPIO_DIR_IN);
57*054af8f2SPo Xu }
58*054af8f2SPo Xu 
59*054af8f2SPo Xu static void mt_set_gpio_out_chip(uint32_t pin, int output)
60*054af8f2SPo Xu {
61*054af8f2SPo Xu 	uint32_t pos, bit;
62*054af8f2SPo Xu 
63*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
64*054af8f2SPo Xu 	assert(output < MT_GPIO_OUT_MAX);
65*054af8f2SPo Xu 
66*054af8f2SPo Xu 	pos = pin / MAX_GPIO_REG_BITS;
67*054af8f2SPo Xu 	bit = pin % MAX_GPIO_REG_BITS;
68*054af8f2SPo Xu 
69*054af8f2SPo Xu 	if (output == MT_GPIO_OUT_ZERO) {
70*054af8f2SPo Xu 		mmio_write_32(DOUT_BASE + 0x10U * pos + CLR, 1U << bit);
71*054af8f2SPo Xu 	} else {
72*054af8f2SPo Xu 		mmio_write_32(DOUT_BASE + 0x10U * pos + SET, 1U << bit);
73*054af8f2SPo Xu 	}
74*054af8f2SPo Xu }
75*054af8f2SPo Xu 
76*054af8f2SPo Xu static int mt_get_gpio_in_chip(uint32_t pin)
77*054af8f2SPo Xu {
78*054af8f2SPo Xu 	uint32_t pos, bit;
79*054af8f2SPo Xu 	uint32_t reg;
80*054af8f2SPo Xu 
81*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
82*054af8f2SPo Xu 
83*054af8f2SPo Xu 	pos = pin / MAX_GPIO_REG_BITS;
84*054af8f2SPo Xu 	bit = pin % MAX_GPIO_REG_BITS;
85*054af8f2SPo Xu 
86*054af8f2SPo Xu 	reg = mmio_read_32(DIN_BASE + 0x10U * pos);
87*054af8f2SPo Xu 	return (((reg & (1U << bit)) != 0U) ? 1 : 0);
88*054af8f2SPo Xu }
89*054af8f2SPo Xu 
90*054af8f2SPo Xu static uintptr_t mt_gpio_find_reg_addr(uint32_t pin)
91*054af8f2SPo Xu {
92*054af8f2SPo Xu 	uintptr_t reg_addr = 0U;
93*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
94*054af8f2SPo Xu 
95*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
96*054af8f2SPo Xu 
97*054af8f2SPo Xu 	switch (gpio_info.base & 0x0f) {
98*054af8f2SPo Xu 	case 0:
99*054af8f2SPo Xu 		reg_addr = IOCFG_RM_BASE;
100*054af8f2SPo Xu 		break;
101*054af8f2SPo Xu 	case 1:
102*054af8f2SPo Xu 		reg_addr = IOCFG_BM_BASE;
103*054af8f2SPo Xu 		break;
104*054af8f2SPo Xu 	case 2:
105*054af8f2SPo Xu 		reg_addr = IOCFG_BL_BASE;
106*054af8f2SPo Xu 		break;
107*054af8f2SPo Xu 	case 3:
108*054af8f2SPo Xu 		reg_addr = IOCFG_BR_BASE;
109*054af8f2SPo Xu 		break;
110*054af8f2SPo Xu 	case 4:
111*054af8f2SPo Xu 		reg_addr = IOCFG_LM_BASE;
112*054af8f2SPo Xu 		break;
113*054af8f2SPo Xu 	case 5:
114*054af8f2SPo Xu 		reg_addr = IOCFG_LB_BASE;
115*054af8f2SPo Xu 		break;
116*054af8f2SPo Xu 	case 6:
117*054af8f2SPo Xu 		reg_addr = IOCFG_RT_BASE;
118*054af8f2SPo Xu 		break;
119*054af8f2SPo Xu 	case 7:
120*054af8f2SPo Xu 		reg_addr = IOCFG_LT_BASE;
121*054af8f2SPo Xu 		break;
122*054af8f2SPo Xu 	case 8:
123*054af8f2SPo Xu 		reg_addr = IOCFG_TL_BASE;
124*054af8f2SPo Xu 		break;
125*054af8f2SPo Xu 	default:
126*054af8f2SPo Xu 		break;
127*054af8f2SPo Xu 	}
128*054af8f2SPo Xu 
129*054af8f2SPo Xu 	return reg_addr;
130*054af8f2SPo Xu }
131*054af8f2SPo Xu 
132*054af8f2SPo Xu static void mt_gpio_set_spec_pull_pupd(uint32_t pin, int enable,
133*054af8f2SPo Xu 			       int select)
134*054af8f2SPo Xu {
135*054af8f2SPo Xu 	uintptr_t reg1;
136*054af8f2SPo Xu 	uintptr_t reg2;
137*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
138*054af8f2SPo Xu 
139*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
140*054af8f2SPo Xu 	uint32_t bit = gpio_info.bit;
141*054af8f2SPo Xu 
142*054af8f2SPo Xu 	reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
143*054af8f2SPo Xu 	reg2 = reg1 + (gpio_info.base & 0xf0);
144*054af8f2SPo Xu 	if (enable == MT_GPIO_PULL_ENABLE) {
145*054af8f2SPo Xu 		mmio_write_32(reg2 + SET, (1U << bit));
146*054af8f2SPo Xu 		if (select == MT_GPIO_PULL_DOWN) {
147*054af8f2SPo Xu 			mmio_write_32(reg1 + SET, (1U << bit));
148*054af8f2SPo Xu 		} else {
149*054af8f2SPo Xu 			mmio_write_32(reg1 + CLR, (1U << bit));
150*054af8f2SPo Xu 		}
151*054af8f2SPo Xu 	} else {
152*054af8f2SPo Xu 		mmio_write_32(reg2 + CLR, (1U << bit));
153*054af8f2SPo Xu 		mmio_write_32((reg2 + 0x010U) + CLR, (1U << bit));
154*054af8f2SPo Xu 	}
155*054af8f2SPo Xu }
156*054af8f2SPo Xu 
157*054af8f2SPo Xu static void mt_gpio_set_pull_pu_pd(uint32_t pin, int enable,
158*054af8f2SPo Xu 				 int select)
159*054af8f2SPo Xu {
160*054af8f2SPo Xu 	uintptr_t reg1;
161*054af8f2SPo Xu 	uintptr_t reg2;
162*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
163*054af8f2SPo Xu 
164*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
165*054af8f2SPo Xu 	uint32_t bit = gpio_info.bit;
166*054af8f2SPo Xu 
167*054af8f2SPo Xu 	reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
168*054af8f2SPo Xu 	reg2 = reg1 - (gpio_info.base & 0xf0);
169*054af8f2SPo Xu 
170*054af8f2SPo Xu 	if (enable == MT_GPIO_PULL_ENABLE) {
171*054af8f2SPo Xu 		if (select == MT_GPIO_PULL_DOWN) {
172*054af8f2SPo Xu 			mmio_write_32(reg1 + CLR, (1U << bit));
173*054af8f2SPo Xu 			mmio_write_32(reg2 + SET, (1U << bit));
174*054af8f2SPo Xu 		} else {
175*054af8f2SPo Xu 			mmio_write_32(reg2 + CLR, (1U << bit));
176*054af8f2SPo Xu 			mmio_write_32(reg1 + SET, (1U << bit));
177*054af8f2SPo Xu 		}
178*054af8f2SPo Xu 	} else {
179*054af8f2SPo Xu 		mmio_write_32(reg1 + CLR, (1U << bit));
180*054af8f2SPo Xu 		mmio_write_32(reg2 + CLR, (1U << bit));
181*054af8f2SPo Xu 	}
182*054af8f2SPo Xu }
183*054af8f2SPo Xu 
184*054af8f2SPo Xu static void mt_gpio_set_pull_chip(uint32_t pin, int enable,
185*054af8f2SPo Xu 		   int select)
186*054af8f2SPo Xu {
187*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
188*054af8f2SPo Xu 
189*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
190*054af8f2SPo Xu 	if (gpio_info.flag) {
191*054af8f2SPo Xu 		mt_gpio_set_spec_pull_pupd(pin, enable, select);
192*054af8f2SPo Xu 	} else {
193*054af8f2SPo Xu 		mt_gpio_set_pull_pu_pd(pin, enable, select);
194*054af8f2SPo Xu 	}
195*054af8f2SPo Xu }
196*054af8f2SPo Xu 
197*054af8f2SPo Xu static int mt_gpio_get_spec_pull_pupd(uint32_t pin)
198*054af8f2SPo Xu {
199*054af8f2SPo Xu 	uintptr_t reg1;
200*054af8f2SPo Xu 	uintptr_t reg2;
201*054af8f2SPo Xu 	uint32_t r0;
202*054af8f2SPo Xu 	uint32_t r1;
203*054af8f2SPo Xu 
204*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
205*054af8f2SPo Xu 
206*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
207*054af8f2SPo Xu 	uint32_t bit = gpio_info.bit;
208*054af8f2SPo Xu 
209*054af8f2SPo Xu 	reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
210*054af8f2SPo Xu 	reg2 = reg1 + (gpio_info.base & 0xf0);
211*054af8f2SPo Xu 
212*054af8f2SPo Xu 	r0 = (mmio_read_32(reg2) >> bit) & 1U;
213*054af8f2SPo Xu 	r1 = (mmio_read_32(reg2 + 0x010) >> bit) & 1U;
214*054af8f2SPo Xu 	if (r0 == 0U && r1 == 0U) {
215*054af8f2SPo Xu 		return MT_GPIO_PULL_NONE;
216*054af8f2SPo Xu 	} else {
217*054af8f2SPo Xu 		if (mmio_read_32(reg1) & (1U << bit)) {
218*054af8f2SPo Xu 			return MT_GPIO_PULL_DOWN;
219*054af8f2SPo Xu 		} else {
220*054af8f2SPo Xu 			return MT_GPIO_PULL_UP;
221*054af8f2SPo Xu 		}
222*054af8f2SPo Xu 	}
223*054af8f2SPo Xu }
224*054af8f2SPo Xu 
225*054af8f2SPo Xu static int mt_gpio_get_pull_pu_pd(uint32_t pin)
226*054af8f2SPo Xu {
227*054af8f2SPo Xu 	uintptr_t reg1;
228*054af8f2SPo Xu 	uintptr_t reg2;
229*054af8f2SPo Xu 	uint32_t pu;
230*054af8f2SPo Xu 	uint32_t pd;
231*054af8f2SPo Xu 
232*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
233*054af8f2SPo Xu 
234*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
235*054af8f2SPo Xu 	uint32_t bit = gpio_info.bit;
236*054af8f2SPo Xu 
237*054af8f2SPo Xu 	reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset;
238*054af8f2SPo Xu 	reg2 = reg1 - (gpio_info.base & 0xf0);
239*054af8f2SPo Xu 	pu = (mmio_read_32(reg1) >> bit) & 1U;
240*054af8f2SPo Xu 	pd = (mmio_read_32(reg2) >> bit) & 1U;
241*054af8f2SPo Xu 	if (pu == 1U) {
242*054af8f2SPo Xu 		return MT_GPIO_PULL_UP;
243*054af8f2SPo Xu 	} else if (pd == 1U) {
244*054af8f2SPo Xu 		return MT_GPIO_PULL_DOWN;
245*054af8f2SPo Xu 	} else {
246*054af8f2SPo Xu 		return MT_GPIO_PULL_NONE;
247*054af8f2SPo Xu 	}
248*054af8f2SPo Xu }
249*054af8f2SPo Xu 
250*054af8f2SPo Xu static int mt_gpio_get_pull_chip(uint32_t pin)
251*054af8f2SPo Xu {
252*054af8f2SPo Xu 	struct mt_pin_info gpio_info;
253*054af8f2SPo Xu 
254*054af8f2SPo Xu 	gpio_info = mt8192_pin_infos[pin];
255*054af8f2SPo Xu 	if (gpio_info.flag) {
256*054af8f2SPo Xu 		return mt_gpio_get_spec_pull_pupd(pin);
257*054af8f2SPo Xu 	} else {
258*054af8f2SPo Xu 		return mt_gpio_get_pull_pu_pd(pin);
259*054af8f2SPo Xu 	}
260*054af8f2SPo Xu }
261*054af8f2SPo Xu 
262*054af8f2SPo Xu static void mt_set_gpio_pull_select_chip(uint32_t pin, int sel)
263*054af8f2SPo Xu {
264*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
265*054af8f2SPo Xu 
266*054af8f2SPo Xu 	if (sel == MT_GPIO_PULL_NONE) {
267*054af8f2SPo Xu 		mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_DISABLE, MT_GPIO_PULL_DOWN);
268*054af8f2SPo Xu 	} else if (sel == MT_GPIO_PULL_UP) {
269*054af8f2SPo Xu 		mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_UP);
270*054af8f2SPo Xu 	} else if (sel == MT_GPIO_PULL_DOWN) {
271*054af8f2SPo Xu 		mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_DOWN);
272*054af8f2SPo Xu 	}
273*054af8f2SPo Xu }
274*054af8f2SPo Xu 
275*054af8f2SPo Xu /* get pull-up or pull-down, regardless of resistor value */
276*054af8f2SPo Xu static int mt_get_gpio_pull_select_chip(uint32_t pin)
277*054af8f2SPo Xu {
278*054af8f2SPo Xu 	assert(pin < MAX_GPIO_PIN);
279*054af8f2SPo Xu 
280*054af8f2SPo Xu 	return mt_gpio_get_pull_chip(pin);
281*054af8f2SPo Xu }
282*054af8f2SPo Xu 
283*054af8f2SPo Xu static void mt_set_gpio_dir(int gpio, int direction)
284*054af8f2SPo Xu {
285*054af8f2SPo Xu 	mt_set_gpio_dir_chip((uint32_t)gpio, direction);
286*054af8f2SPo Xu }
287*054af8f2SPo Xu 
288*054af8f2SPo Xu static int mt_get_gpio_dir(int gpio)
289*054af8f2SPo Xu {
290*054af8f2SPo Xu 	uint32_t pin;
291*054af8f2SPo Xu 
292*054af8f2SPo Xu 	pin = (uint32_t)gpio;
293*054af8f2SPo Xu 	return mt_get_gpio_dir_chip(pin);
294*054af8f2SPo Xu }
295*054af8f2SPo Xu 
296*054af8f2SPo Xu static void mt_set_gpio_pull(int gpio, int pull)
297*054af8f2SPo Xu {
298*054af8f2SPo Xu 	uint32_t pin;
299*054af8f2SPo Xu 
300*054af8f2SPo Xu 	pin = (uint32_t)gpio;
301*054af8f2SPo Xu 	mt_set_gpio_pull_select_chip(pin, pull);
302*054af8f2SPo Xu }
303*054af8f2SPo Xu 
304*054af8f2SPo Xu static int mt_get_gpio_pull(int gpio)
305*054af8f2SPo Xu {
306*054af8f2SPo Xu 	uint32_t pin;
307*054af8f2SPo Xu 
308*054af8f2SPo Xu 	pin = (uint32_t)gpio;
309*054af8f2SPo Xu 	return mt_get_gpio_pull_select_chip(pin);
310*054af8f2SPo Xu }
311*054af8f2SPo Xu 
312*054af8f2SPo Xu static void mt_set_gpio_out(int gpio, int value)
313*054af8f2SPo Xu {
314*054af8f2SPo Xu 	uint32_t pin;
315*054af8f2SPo Xu 
316*054af8f2SPo Xu 	pin = (uint32_t)gpio;
317*054af8f2SPo Xu 	mt_set_gpio_out_chip(pin, value);
318*054af8f2SPo Xu }
319*054af8f2SPo Xu 
320*054af8f2SPo Xu static int mt_get_gpio_in(int gpio)
321*054af8f2SPo Xu {
322*054af8f2SPo Xu 	uint32_t pin;
323*054af8f2SPo Xu 
324*054af8f2SPo Xu 	pin = (uint32_t)gpio;
325*054af8f2SPo Xu 	return mt_get_gpio_in_chip(pin);
326*054af8f2SPo Xu }
327*054af8f2SPo Xu 
328*054af8f2SPo Xu const gpio_ops_t mtgpio_ops = {
329*054af8f2SPo Xu 	 .get_direction = mt_get_gpio_dir,
330*054af8f2SPo Xu 	 .set_direction = mt_set_gpio_dir,
331*054af8f2SPo Xu 	 .get_value = mt_get_gpio_in,
332*054af8f2SPo Xu 	 .set_value = mt_set_gpio_out,
333*054af8f2SPo Xu 	 .set_pull = mt_set_gpio_pull,
334*054af8f2SPo Xu 	 .get_pull = mt_get_gpio_pull,
335*054af8f2SPo Xu };
336*054af8f2SPo Xu 
337*054af8f2SPo Xu void plat_mt8192_gpio_init(void)
338*054af8f2SPo Xu {
339*054af8f2SPo Xu 	gpio_init(&mtgpio_ops);
340*054af8f2SPo Xu }
341