1 // SPDX-License-Identifier:      GPL-2.0+
2 /*
3  * Copyright (C) 2020 Broadcom
4  */
5 
6 #include <common.h>
7 #include <errno.h>
8 #include <asm/gpio.h>
9 #include <asm/io.h>
10 #include <dm.h>
11 #include <dm/device_compat.h>
12 #include <dm/devres.h>
13 #include <dm/pinctrl.h>
14 
15 /*
16  * There are five GPIO bank register. Each bank can configure max of 32 gpios.
17  * BANK0 - gpios 0 to 31
18  * BANK1 - gpios 32 to 63
19  * BANK2 - gpios 64 to 95
20  * BANK3 - gpios 96 to 127
21  * BANK4 - gpios 128 to 150
22  *
23  * Offset difference between consecutive bank register is 0x200
24  */
25 #define NGPIO_PER_BANK		32
26 #define GPIO_BANK_SIZE		0x200
27 #define GPIO_BANK(pin)		((pin) / NGPIO_PER_BANK)
28 #define GPIO_SHIFT(pin)		((pin) % NGPIO_PER_BANK)
29 #define GPIO_REG(pin, reg)	(GPIO_BANK_SIZE * GPIO_BANK(pin) + (reg))
30 
31 /* device register offset */
32 #define DATA_IN_OFFSET   0x00
33 #define DATA_OUT_OFFSET  0x04
34 #define OUT_EN_OFFSET    0x08
35 
36 /**
37  * struct iproc_gpio_pctrl_map - gpio and pinctrl mapping
38  * @gpio_pin:	start of gpio number in gpio-ranges
39  * @pctrl_pin:	start of pinctrl number in gpio-ranges
40  * @npins:	total number of pins in gpio-ranges
41  * @node:	list node
42  */
43 struct iproc_gpio_pctrl_map {
44 	u32 gpio_pin;
45 	u32 pctrl_pin;
46 	u32 npins;
47 	struct list_head node;
48 };
49 
50 /**
51  * struct iproc_gpio_pctrl_map - gpio device instance
52  * @pinctrl_dev:pointer to pinctrl device
53  * @gpiomap:	list node having mapping between gpio and pinctrl
54  * @base:	I/O register base address of gpio device
55  * @name:	gpio device name, ex GPIO0, GPIO1
56  * @ngpios:	total number of gpios
57  */
58 struct iproc_gpio_plat {
59 	struct udevice *pinctrl_dev;
60 	struct list_head gpiomap;
61 	void __iomem *base;
62 	char *name;
63 	u32 ngpios;
64 };
65 
66 /**
67  * iproc_gpio_set_bit - set or clear one bit in an iproc GPIO register.
68  *
69  * The bit relates to a GPIO pin.
70  *
71  * @plat: iproc GPIO device
72  * @reg: register offset
73  * @gpio: GPIO pin
74  * @set: set or clear
75  */
iproc_gpio_set_bit(struct iproc_gpio_plat * plat,u32 reg,u32 gpio,bool set)76 static inline void iproc_gpio_set_bit(struct iproc_gpio_plat *plat,
77 				      u32 reg, u32 gpio, bool set)
78 {
79 	u32 offset = GPIO_REG(gpio, reg);
80 	u32 shift = GPIO_SHIFT(gpio);
81 
82 	clrsetbits_le32(plat->base + offset, BIT(shift),
83 			(set ? BIT(shift) : 0));
84 }
85 
iproc_gpio_get_bit(struct iproc_gpio_plat * plat,u32 reg,u32 gpio)86 static inline bool iproc_gpio_get_bit(struct iproc_gpio_plat *plat,
87 				      u32 reg, u32 gpio)
88 {
89 	u32 offset = GPIO_REG(gpio, reg);
90 	u32 shift = GPIO_SHIFT(gpio);
91 
92 	return readl(plat->base + offset) & BIT(shift);
93 }
94 
95 /**
96  * iproc_get_gpio_pctrl_mapping() - get associated pinctrl pin from gpio pin
97  *
98  * @plat: iproc GPIO device
99  * @gpio: GPIO pin
100  */
iproc_get_pctrl_from_gpio(struct iproc_gpio_plat * plat,u32 gpio)101 static u32 iproc_get_pctrl_from_gpio(struct iproc_gpio_plat *plat, u32 gpio)
102 {
103 	struct iproc_gpio_pctrl_map *range = NULL;
104 	struct list_head *pos, *tmp;
105 	u32 ret = 0;
106 
107 	list_for_each_safe(pos, tmp, &plat->gpiomap) {
108 		range = list_entry(pos, struct iproc_gpio_pctrl_map, node);
109 		if (gpio == range->gpio_pin ||
110 		    gpio < (range->gpio_pin + range->npins)) {
111 			ret = range->pctrl_pin + (gpio - range->gpio_pin);
112 			break;
113 		}
114 	}
115 
116 	return ret;
117 }
118 
119 /**
120  * iproc_get_gpio_pctrl_mapping() - get mapping between gpio and pinctrl
121  *
122  * Read dt node "gpio-ranges" to get gpio and pinctrl mapping and store
123  * in private data structure to use it later while enabling gpio.
124  *
125  * @dev: pointer to GPIO device
126  * @return 0 on success and -ENOMEM on failure
127  */
iproc_get_gpio_pctrl_mapping(struct udevice * dev)128 static int iproc_get_gpio_pctrl_mapping(struct udevice *dev)
129 {
130 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
131 	struct iproc_gpio_pctrl_map *range = NULL;
132 	struct ofnode_phandle_args args;
133 	int index = 0, ret;
134 
135 	for (;; index++) {
136 		ret = dev_read_phandle_with_args(dev, "gpio-ranges",
137 						 NULL, 3, index, &args);
138 		if (ret)
139 			break;
140 
141 		range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
142 		if (!range)
143 			return -ENOMEM;
144 
145 		range->gpio_pin = args.args[0];
146 		range->pctrl_pin = args.args[1];
147 		range->npins = args.args[2];
148 		list_add_tail(&range->node, &plat->gpiomap);
149 	}
150 
151 	return 0;
152 }
153 
iproc_gpio_request(struct udevice * dev,u32 gpio,const char * label)154 static int iproc_gpio_request(struct udevice *dev, u32 gpio, const char *label)
155 {
156 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
157 	u32 pctrl;
158 
159 	/* nothing to do if there is no corresponding pinctrl device */
160 	if (!plat->pinctrl_dev)
161 		return 0;
162 
163 	pctrl = iproc_get_pctrl_from_gpio(plat, gpio);
164 
165 	return pinctrl_request(plat->pinctrl_dev, pctrl, 0);
166 }
167 
iproc_gpio_direction_input(struct udevice * dev,u32 gpio)168 static int iproc_gpio_direction_input(struct udevice *dev, u32 gpio)
169 {
170 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
171 
172 	iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, false);
173 	dev_dbg(dev, "gpio:%u set input\n", gpio);
174 
175 	return 0;
176 }
177 
iproc_gpio_direction_output(struct udevice * dev,u32 gpio,int value)178 static int iproc_gpio_direction_output(struct udevice *dev, u32 gpio, int value)
179 {
180 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
181 
182 	iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, true);
183 	iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value);
184 	dev_dbg(dev, "gpio:%u set output, value:%d\n", gpio, value);
185 
186 	return 0;
187 }
188 
iproc_gpio_get_value(struct udevice * dev,u32 gpio)189 static int iproc_gpio_get_value(struct udevice *dev, u32 gpio)
190 {
191 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
192 	int value;
193 
194 	value = iproc_gpio_get_bit(plat, DATA_IN_OFFSET, gpio);
195 	dev_dbg(dev, "gpio:%u get, value:%d\n", gpio, value);
196 
197 	return value;
198 }
199 
iproc_gpio_set_value(struct udevice * dev,u32 gpio,int value)200 static int iproc_gpio_set_value(struct udevice *dev, u32 gpio, int value)
201 {
202 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
203 
204 	if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio))
205 		iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value);
206 
207 	dev_dbg(dev, "gpio:%u set, value:%d\n", gpio, value);
208 	return 0;
209 }
210 
iproc_gpio_get_function(struct udevice * dev,u32 gpio)211 static int iproc_gpio_get_function(struct udevice *dev, u32 gpio)
212 {
213 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
214 
215 	if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio))
216 		return GPIOF_OUTPUT;
217 	else
218 		return GPIOF_INPUT;
219 }
220 
iproc_gpio_of_to_plat(struct udevice * dev)221 static int iproc_gpio_of_to_plat(struct udevice *dev)
222 {
223 	struct iproc_gpio_plat *plat = dev_get_plat(dev);
224 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
225 	int ret;
226 	char name[10];
227 
228 	plat->base = dev_read_addr_ptr(dev);
229 	if (!plat->base) {
230 		debug("%s: Failed to get base address\n", __func__);
231 		return -EINVAL;
232 	}
233 
234 	ret = dev_read_u32(dev, "ngpios", &plat->ngpios);
235 	if (ret < 0) {
236 		dev_err(dev, "%s: Failed to get ngpios\n", __func__);
237 		return ret;
238 	}
239 
240 	uclass_get_device_by_phandle(UCLASS_PINCTRL, dev, "gpio-ranges",
241 				     &plat->pinctrl_dev);
242 	if (ret < 0) {
243 		dev_err(dev, "%s: Failed to get pinctrl phandle\n", __func__);
244 		return ret;
245 	}
246 
247 	INIT_LIST_HEAD(&plat->gpiomap);
248 	ret = iproc_get_gpio_pctrl_mapping(dev);
249 	if (ret < 0) {
250 		dev_err(dev, "%s: Failed to get gpio to pctrl map ret(%d)\n",
251 			__func__, ret);
252 		return ret;
253 	}
254 
255 	snprintf(name, sizeof(name), "GPIO%d", dev_seq(dev));
256 	plat->name = strdup(name);
257 	if (!plat->name)
258 		return -ENOMEM;
259 
260 	uc_priv->gpio_count = plat->ngpios;
261 	uc_priv->bank_name = plat->name;
262 
263 	dev_info(dev, ":bank name(%s) base %p, #gpios %d\n",
264 		 plat->name, plat->base, plat->ngpios);
265 
266 	return 0;
267 }
268 
269 static const struct dm_gpio_ops iproc_gpio_ops = {
270 	.request		= iproc_gpio_request,
271 	.direction_input	= iproc_gpio_direction_input,
272 	.direction_output	= iproc_gpio_direction_output,
273 	.get_value		= iproc_gpio_get_value,
274 	.set_value		= iproc_gpio_set_value,
275 	.get_function		= iproc_gpio_get_function,
276 };
277 
278 static const struct udevice_id iproc_gpio_ids[] = {
279 	{ .compatible = "brcm,iproc-gpio" },
280 	{ }
281 };
282 
283 U_BOOT_DRIVER(iproc_gpio) = {
284 	.name			= "iproc_gpio",
285 	.id			= UCLASS_GPIO,
286 	.of_match		= iproc_gpio_ids,
287 	.ops			= &iproc_gpio_ops,
288 	.of_to_plat	= iproc_gpio_of_to_plat,
289 	.plat_auto	= sizeof(struct iproc_gpio_plat),
290 };
291