2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
8 #include <delay_timer.h>
12 #include <plat_private.h>
14 #include <platform_def.h>
17 uint32_t gpio_port
[] = {
30 uint32_t inttype_level
;
31 uint32_t int_polarity
;
36 static uint32_t store_grf_gpio
[(GRF_GPIO2D_HE
- GRF_GPIO2A_IOMUX
) / 4 + 1];
38 #define SWPORTA_DR 0x00
39 #define SWPORTA_DDR 0x04
42 #define INTTYPE_LEVEL 0x38
43 #define INT_POLARITY 0x3c
47 #define EXT_PORTA 0x50
48 #define PMU_GPIO_PORT0 0
49 #define PMU_GPIO_PORT1 1
54 #define PMU_GRF_GPIO0A_P 0x40
55 #define GRF_GPIO2A_P 0xe040
56 #define GPIO_P_MASK 0x03
58 #define GET_GPIO_PORT(pin) (pin / 32)
59 #define GET_GPIO_NUM(pin) (pin % 32)
60 #define GET_GPIO_BANK(pin) ((pin % 32) / 8)
61 #define GET_GPIO_ID(pin) ((pin % 32) % 8)
63 /* returns old clock state, enables clock, in order to do GPIO access */
64 static int gpio_get_clock(uint32_t gpio_number
)
66 uint32_t port
= GET_GPIO_PORT(gpio_number
);
67 uint32_t clock_state
= 0;
73 clock_state
= (mmio_read_32(PMUCRU_BASE
+
74 CRU_PMU_CLKGATE_CON(1)) >>
75 PCLK_GPIO0_GATE_SHIFT
) & 0x01;
76 mmio_write_32(PMUCRU_BASE
+ CRU_PMU_CLKGATE_CON(1),
77 BITS_WITH_WMASK(0, CLK_GATE_MASK
,
78 PCLK_GPIO0_GATE_SHIFT
));
81 clock_state
= (mmio_read_32(PMUCRU_BASE
+
82 CRU_PMU_CLKGATE_CON(1)) >>
83 PCLK_GPIO1_GATE_SHIFT
) & 0x01;
84 mmio_write_32(PMUCRU_BASE
+ CRU_PMU_CLKGATE_CON(1),
85 BITS_WITH_WMASK(0, CLK_GATE_MASK
,
86 PCLK_GPIO1_GATE_SHIFT
));
89 clock_state
= (mmio_read_32(CRU_BASE
+
90 CRU_CLKGATE_CON(31)) >>
91 PCLK_GPIO2_GATE_SHIFT
) & 0x01;
92 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
93 BITS_WITH_WMASK(0, CLK_GATE_MASK
,
94 PCLK_GPIO2_GATE_SHIFT
));
97 clock_state
= (mmio_read_32(CRU_BASE
+
98 CRU_CLKGATE_CON(31)) >>
99 PCLK_GPIO3_GATE_SHIFT
) & 0x01;
100 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
101 BITS_WITH_WMASK(0, CLK_GATE_MASK
,
102 PCLK_GPIO3_GATE_SHIFT
));
105 clock_state
= (mmio_read_32(CRU_BASE
+
106 CRU_CLKGATE_CON(31)) >>
107 PCLK_GPIO4_GATE_SHIFT
) & 0x01;
108 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
109 BITS_WITH_WMASK(0, CLK_GATE_MASK
,
110 PCLK_GPIO4_GATE_SHIFT
));
119 /* restores old state of gpio clock */
120 void gpio_put_clock(uint32_t gpio_number
, uint32_t clock_state
)
122 uint32_t port
= GET_GPIO_PORT(gpio_number
);
126 mmio_write_32(PMUCRU_BASE
+ CRU_PMU_CLKGATE_CON(1),
127 BITS_WITH_WMASK(clock_state
, CLK_GATE_MASK
,
128 PCLK_GPIO0_GATE_SHIFT
));
131 mmio_write_32(PMUCRU_BASE
+ CRU_PMU_CLKGATE_CON(1),
132 BITS_WITH_WMASK(clock_state
, CLK_GATE_MASK
,
133 PCLK_GPIO1_GATE_SHIFT
));
136 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
137 BITS_WITH_WMASK(clock_state
, CLK_GATE_MASK
,
138 PCLK_GPIO2_GATE_SHIFT
));
141 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
142 BITS_WITH_WMASK(clock_state
, CLK_GATE_MASK
,
143 PCLK_GPIO3_GATE_SHIFT
));
147 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
148 BITS_WITH_WMASK(clock_state
, CLK_GATE_MASK
,
149 PCLK_GPIO4_GATE_SHIFT
));
156 static int get_pull(int gpio
)
158 uint32_t port
= GET_GPIO_PORT(gpio
);
159 uint32_t bank
= GET_GPIO_BANK(gpio
);
160 uint32_t id
= GET_GPIO_ID(gpio
);
161 uint32_t val
, clock_state
;
163 assert((port
< 5) && (bank
< 4));
165 clock_state
= gpio_get_clock(gpio
);
167 if (port
== PMU_GPIO_PORT0
|| port
== PMU_GPIO_PORT1
) {
168 val
= mmio_read_32(PMUGRF_BASE
+ PMU_GRF_GPIO0A_P
+
169 port
* 16 + bank
* 4);
170 val
= (val
>> (id
* 2)) & GPIO_P_MASK
;
172 val
= mmio_read_32(GRF_BASE
+ GRF_GPIO2A_P
+
173 (port
- 2) * 16 + bank
* 4);
174 val
= (val
>> (id
* 2)) & GPIO_P_MASK
;
176 gpio_put_clock(gpio
, clock_state
);
179 * in gpio0a, gpio0b, gpio2c, gpio2d,
184 * different with other gpio, so need to correct it
186 if (((port
== 0) && (bank
< 2)) || ((port
== 2) && (bank
> 1))) {
190 val
= GPIO_PULL_DOWN
;
198 static void set_pull(int gpio
, int pull
)
200 uint32_t port
= GET_GPIO_PORT(gpio
);
201 uint32_t bank
= GET_GPIO_BANK(gpio
);
202 uint32_t id
= GET_GPIO_ID(gpio
);
203 uint32_t clock_state
;
205 assert((port
< 5) && (bank
< 4));
207 clock_state
= gpio_get_clock(gpio
);
210 * in gpio0a, gpio0b, gpio2c, gpio2d,
215 * different with other gpio, so need to correct it
217 if (((port
== 0) && (bank
< 2)) || ((port
== 2) && (bank
> 1))) {
218 if (pull
== GPIO_PULL_UP
)
220 else if (pull
== GPIO_PULL_DOWN
)
226 if (port
== PMU_GPIO_PORT0
|| port
== PMU_GPIO_PORT1
) {
227 mmio_write_32(PMUGRF_BASE
+ PMU_GRF_GPIO0A_P
+
228 port
* 16 + bank
* 4,
229 BITS_WITH_WMASK(pull
, GPIO_P_MASK
, id
* 2));
231 mmio_write_32(GRF_BASE
+ GRF_GPIO2A_P
+
232 (port
- 2) * 16 + bank
* 4,
233 BITS_WITH_WMASK(pull
, GPIO_P_MASK
, id
* 2));
235 gpio_put_clock(gpio
, clock_state
);
238 static void set_direction(int gpio
, int direction
)
240 uint32_t port
= GET_GPIO_PORT(gpio
);
241 uint32_t num
= GET_GPIO_NUM(gpio
);
242 uint32_t clock_state
;
244 assert((port
< 5) && (num
< 32));
246 clock_state
= gpio_get_clock(gpio
);
250 * #define GPIO_DIR_OUT 0
251 * #define GPIO_DIR_IN 1
252 * but rk3399 gpio direction 1: output, 0: input
253 * so need to revert direction value
255 mmio_setbits_32(gpio_port
[port
] + SWPORTA_DDR
, !direction
<< num
);
256 gpio_put_clock(gpio
, clock_state
);
259 static int get_direction(int gpio
)
261 uint32_t port
= GET_GPIO_PORT(gpio
);
262 uint32_t num
= GET_GPIO_NUM(gpio
);
263 int direction
, clock_state
;
265 assert((port
< 5) && (num
< 32));
267 clock_state
= gpio_get_clock(gpio
);
271 * #define GPIO_DIR_OUT 0
272 * #define GPIO_DIR_IN 1
273 * but rk3399 gpio direction 1: output, 0: input
274 * so need to revert direction value
276 direction
= !((mmio_read_32(gpio_port
[port
] +
277 SWPORTA_DDR
) >> num
) & 0x1);
278 gpio_put_clock(gpio
, clock_state
);
283 static int get_value(int gpio
)
285 uint32_t port
= GET_GPIO_PORT(gpio
);
286 uint32_t num
= GET_GPIO_NUM(gpio
);
287 int value
, clock_state
;
289 assert((port
< 5) && (num
< 32));
291 clock_state
= gpio_get_clock(gpio
);
292 value
= (mmio_read_32(gpio_port
[port
] + EXT_PORTA
) >> num
) & 0x1;
293 gpio_put_clock(gpio
, clock_state
);
298 static void set_value(int gpio
, int value
)
300 uint32_t port
= GET_GPIO_PORT(gpio
);
301 uint32_t num
= GET_GPIO_NUM(gpio
);
302 uint32_t clock_state
;
304 assert((port
< 5) && (num
< 32));
306 clock_state
= gpio_get_clock(gpio
);
307 mmio_clrsetbits_32(gpio_port
[port
] + SWPORTA_DR
, 1 << num
,
309 gpio_put_clock(gpio
, clock_state
);
312 void plat_rockchip_save_gpio(void)
315 uint32_t cru_gate_save
;
317 cru_gate_save
= mmio_read_32(CRU_BASE
+ CRU_CLKGATE_CON(31));
320 * when shutdown logic, we need to save gpio2 ~ gpio4 register,
321 * we need to enable gpio2 ~ gpio4 clock here, since it may be gating,
322 * and we do not care gpio0 and gpio1 clock gate, since we never
325 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
326 BITS_WITH_WMASK(0, 0x07, PCLK_GPIO2_GATE_SHIFT
));
329 * since gpio0, gpio1 are pmugpio, they will keep ther value
330 * when shutdown logic power rail, so only need to save gpio2 ~ gpio4
333 for (i
= 2; i
< 5; i
++) {
334 store_gpio
[i
- 2].swporta_dr
=
335 mmio_read_32(gpio_port
[i
] + SWPORTA_DR
);
336 store_gpio
[i
- 2].swporta_ddr
=
337 mmio_read_32(gpio_port
[i
] + SWPORTA_DDR
);
338 store_gpio
[i
- 2].inten
=
339 mmio_read_32(gpio_port
[i
] + INTEN
);
340 store_gpio
[i
- 2].intmask
=
341 mmio_read_32(gpio_port
[i
] + INTMASK
);
342 store_gpio
[i
- 2].inttype_level
=
343 mmio_read_32(gpio_port
[i
] + INTTYPE_LEVEL
);
344 store_gpio
[i
- 2].int_polarity
=
345 mmio_read_32(gpio_port
[i
] + INT_POLARITY
);
346 store_gpio
[i
- 2].debounce
=
347 mmio_read_32(gpio_port
[i
] + DEBOUNCE
);
348 store_gpio
[i
- 2].ls_sync
=
349 mmio_read_32(gpio_port
[i
] + LS_SYNC
);
351 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
352 cru_gate_save
| REG_SOC_WMSK
);
355 * gpio0, gpio1 in pmuiomux, they will keep ther value
356 * when shutdown logic power rail, so only need to save gpio2 ~ gpio4
357 * iomux register value
359 for (i
= 0; i
< ARRAY_SIZE(store_grf_gpio
); i
++)
361 mmio_read_32(GRF_BASE
+ GRF_GPIO2A_IOMUX
+ i
* 4);
364 void plat_rockchip_restore_gpio(void)
367 uint32_t cru_gate_save
;
369 for (i
= 0; i
< ARRAY_SIZE(store_grf_gpio
); i
++)
370 mmio_write_32(GRF_BASE
+ GRF_GPIO2A_IOMUX
+ i
* 4,
371 REG_SOC_WMSK
| store_grf_gpio
[i
]);
373 cru_gate_save
= mmio_read_32(CRU_BASE
+ CRU_CLKGATE_CON(31));
376 * when shutdown logic, we need to save gpio2 ~ gpio4 register,
377 * we need to enable gpio2 ~ gpio4 clock here, since it may be gating,
378 * and we do not care gpio0 and gpio1 clock gate, since we never
381 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
382 BITS_WITH_WMASK(0, 0x07, PCLK_GPIO2_GATE_SHIFT
));
384 for (i
= 2; i
< 5; i
++) {
385 mmio_write_32(gpio_port
[i
] + SWPORTA_DR
,
386 store_gpio
[i
- 2].swporta_dr
);
387 mmio_write_32(gpio_port
[i
] + SWPORTA_DDR
,
388 store_gpio
[i
- 2].swporta_ddr
);
389 mmio_write_32(gpio_port
[i
] + INTEN
, store_gpio
[i
- 2].inten
);
390 mmio_write_32(gpio_port
[i
] + INTMASK
,
391 store_gpio
[i
- 2].intmask
);
392 mmio_write_32(gpio_port
[i
] + INTTYPE_LEVEL
,
393 store_gpio
[i
- 2].inttype_level
);
394 mmio_write_32(gpio_port
[i
] + INT_POLARITY
,
395 store_gpio
[i
- 2].int_polarity
);
396 mmio_write_32(gpio_port
[i
] + DEBOUNCE
,
397 store_gpio
[i
- 2].debounce
);
398 mmio_write_32(gpio_port
[i
] + LS_SYNC
,
399 store_gpio
[i
- 2].ls_sync
);
401 mmio_write_32(CRU_BASE
+ CRU_CLKGATE_CON(31),
402 cru_gate_save
| REG_SOC_WMSK
);
405 const gpio_ops_t rk3399_gpio_ops
= {
406 .get_direction
= get_direction
,
407 .set_direction
= set_direction
,
408 .get_value
= get_value
,
409 .set_value
= set_value
,
410 .set_pull
= set_pull
,
411 .get_pull
= get_pull
,
414 void plat_rockchip_gpio_init(void)
416 gpio_init(&rk3399_gpio_ops
);