xref: /openbmc/u-boot/drivers/gpio/kona_gpio.c (revision 3ebd892f)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Broadcom Corporation.
4  */
5 
6 #include <common.h>
7 #include <asm/io.h>
8 #include <asm/arch/sysmap.h>
9 
10 #define GPIO_BASE				(void *)GPIO2_BASE_ADDR
11 
12 #define GPIO_PASSWD				0x00a5a501
13 #define GPIO_PER_BANK				32
14 #define GPIO_MAX_BANK_NUM			8
15 
16 #define GPIO_BANK(gpio)				((gpio) >> 5)
17 #define GPIO_BITMASK(gpio)	\
18 	(1UL << ((gpio) & (GPIO_PER_BANK - 1)))
19 
20 #define GPIO_OUT_STATUS(bank)			(0x00000000 + ((bank) << 2))
21 #define GPIO_IN_STATUS(bank)			(0x00000020 + ((bank) << 2))
22 #define GPIO_OUT_SET(bank)			(0x00000040 + ((bank) << 2))
23 #define GPIO_OUT_CLEAR(bank)			(0x00000060 + ((bank) << 2))
24 #define GPIO_INT_STATUS(bank)			(0x00000080 + ((bank) << 2))
25 #define GPIO_INT_MASK(bank)			(0x000000a0 + ((bank) << 2))
26 #define GPIO_INT_MSKCLR(bank)			(0x000000c0 + ((bank) << 2))
27 #define GPIO_CONTROL(bank)			(0x00000100 + ((bank) << 2))
28 #define GPIO_PWD_STATUS(bank)			(0x00000500 + ((bank) << 2))
29 
30 #define GPIO_GPPWR_OFFSET			0x00000520
31 
32 #define GPIO_GPCTR0_DBR_SHIFT			5
33 #define GPIO_GPCTR0_DBR_MASK			0x000001e0
34 
35 #define GPIO_GPCTR0_ITR_SHIFT			3
36 #define GPIO_GPCTR0_ITR_MASK			0x00000018
37 #define GPIO_GPCTR0_ITR_CMD_RISING_EDGE		0x00000001
38 #define GPIO_GPCTR0_ITR_CMD_FALLING_EDGE	0x00000002
39 #define GPIO_GPCTR0_ITR_CMD_BOTH_EDGE		0x00000003
40 
41 #define GPIO_GPCTR0_IOTR_MASK			0x00000001
42 #define GPIO_GPCTR0_IOTR_CMD_0UTPUT		0x00000000
43 #define GPIO_GPCTR0_IOTR_CMD_INPUT		0x00000001
44 
45 int gpio_request(unsigned gpio, const char *label)
46 {
47 	unsigned int value, off;
48 
49 	writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
50 	off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
51 	value = readl(GPIO_BASE + off) & ~GPIO_BITMASK(gpio);
52 	writel(value, GPIO_BASE + off);
53 
54 	return 0;
55 }
56 
57 int gpio_free(unsigned gpio)
58 {
59 	unsigned int value, off;
60 
61 	writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
62 	off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
63 	value = readl(GPIO_BASE + off) | GPIO_BITMASK(gpio);
64 	writel(value, GPIO_BASE + off);
65 
66 	return 0;
67 }
68 
69 int gpio_direction_input(unsigned gpio)
70 {
71 	u32 val;
72 
73 	val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
74 	val &= ~GPIO_GPCTR0_IOTR_MASK;
75 	val |= GPIO_GPCTR0_IOTR_CMD_INPUT;
76 	writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
77 
78 	return 0;
79 }
80 
81 int gpio_direction_output(unsigned gpio, int value)
82 {
83 	int bank_id = GPIO_BANK(gpio);
84 	int bitmask = GPIO_BITMASK(gpio);
85 	u32 val, off;
86 
87 	val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
88 	val &= ~GPIO_GPCTR0_IOTR_MASK;
89 	val |= GPIO_GPCTR0_IOTR_CMD_0UTPUT;
90 	writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
91 	off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
92 
93 	val = readl(GPIO_BASE + off);
94 	val |= bitmask;
95 	writel(val, GPIO_BASE + off);
96 
97 	return 0;
98 }
99 
100 int gpio_get_value(unsigned gpio)
101 {
102 	int bank_id = GPIO_BANK(gpio);
103 	int bitmask = GPIO_BITMASK(gpio);
104 	u32 val, off;
105 
106 	/* determine the GPIO pin direction */
107 	val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
108 	val &= GPIO_GPCTR0_IOTR_MASK;
109 
110 	/* read the GPIO bank status */
111 	off = (GPIO_GPCTR0_IOTR_CMD_INPUT == val) ?
112 	    GPIO_IN_STATUS(bank_id) : GPIO_OUT_STATUS(bank_id);
113 	val = readl(GPIO_BASE + off);
114 
115 	/* return the specified bit status */
116 	return !!(val & bitmask);
117 }
118 
119 void gpio_set_value(unsigned gpio, int value)
120 {
121 	int bank_id = GPIO_BANK(gpio);
122 	int bitmask = GPIO_BITMASK(gpio);
123 	u32 val, off;
124 
125 	/* determine the GPIO pin direction */
126 	val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
127 	val &= GPIO_GPCTR0_IOTR_MASK;
128 
129 	/* this function only applies to output pin */
130 	if (GPIO_GPCTR0_IOTR_CMD_INPUT == val) {
131 		printf("%s: Cannot set an input pin %d\n", __func__, gpio);
132 		return;
133 	}
134 
135 	off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
136 
137 	val = readl(GPIO_BASE + off);
138 	val |= bitmask;
139 	writel(val, GPIO_BASE + off);
140 }
141