1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3  * Microsemi SoCs pinctrl driver
4  *
5  * Author: <alexandre.belloni@free-electrons.com>
6  * Author: <gregory.clement@bootlin.com>
7  * License: Dual MIT/GPL
8  * Copyright (c) 2017 Microsemi Corporation
9  */
10 
11 #include <asm/gpio.h>
12 #include <asm/system.h>
13 #include <common.h>
14 #include <config.h>
15 #include <dm.h>
16 #include <dm/device-internal.h>
17 #include <dm/device_compat.h>
18 #include <dm/devres.h>
19 #include <dm/lists.h>
20 #include <dm/pinctrl.h>
21 #include <dm/root.h>
22 #include <errno.h>
23 #include <fdtdec.h>
24 #include <linux/bitops.h>
25 #include <linux/io.h>
26 #include "mscc-common.h"
27 
mscc_writel(unsigned int offset,void * addr)28 static void mscc_writel(unsigned int offset, void *addr)
29 {
30 	if (offset < 32)
31 		writel(BIT(offset), addr);
32 	else
33 		writel(BIT(offset % 32), addr + 4);
34 }
35 
mscc_readl(unsigned int offset,void * addr)36 static unsigned int mscc_readl(unsigned int offset, void *addr)
37 {
38 	if (offset < 32)
39 		return readl(addr);
40 	else
41 		return readl(addr + 4);
42 }
43 
mscc_setbits(unsigned int offset,void * addr)44 static void mscc_setbits(unsigned int offset, void *addr)
45 {
46 	if (offset < 32)
47 		writel(readl(addr) | BIT(offset), addr);
48 	else
49 		writel(readl(addr + 4) | BIT(offset % 32), addr + 4);
50 }
51 
mscc_clrbits(unsigned int offset,void * addr)52 static void mscc_clrbits(unsigned int offset, void *addr)
53 {
54 	if (offset < 32)
55 		writel(readl(addr) & ~BIT(offset), addr);
56 	else
57 		writel(readl(addr + 4) & ~BIT(offset % 32), addr + 4);
58 }
59 
mscc_get_functions_count(struct udevice * dev)60 static int mscc_get_functions_count(struct udevice *dev)
61 {
62 	struct mscc_pinctrl *info = dev_get_priv(dev);
63 
64 	return info->num_func;
65 }
66 
mscc_get_function_name(struct udevice * dev,unsigned int function)67 static const char *mscc_get_function_name(struct udevice *dev,
68 					  unsigned int function)
69 {
70 	struct mscc_pinctrl *info = dev_get_priv(dev);
71 
72 	return info->function_names[function];
73 }
74 
mscc_pin_function_idx(unsigned int pin,unsigned int function,const struct mscc_pin_data * mscc_pins)75 static int mscc_pin_function_idx(unsigned int pin, unsigned int function,
76 				 const struct mscc_pin_data *mscc_pins)
77 {
78 	struct mscc_pin_caps *p = mscc_pins[pin].drv_data;
79 	int i;
80 
81 	for (i = 0; i < MSCC_FUNC_PER_PIN; i++) {
82 		if (function == p->functions[i])
83 			return i;
84 	}
85 
86 	return -1;
87 }
88 
mscc_pinmux_set_mux(struct udevice * dev,unsigned int pin_selector,unsigned int selector)89 static int mscc_pinmux_set_mux(struct udevice *dev,
90 			       unsigned int pin_selector, unsigned int selector)
91 {
92 	struct mscc_pinctrl *info = dev_get_priv(dev);
93 	struct mscc_pin_caps *pin = info->mscc_pins[pin_selector].drv_data;
94 	int f, offset, regoff;
95 
96 	f = mscc_pin_function_idx(pin_selector, selector, info->mscc_pins);
97 	if (f < 0)
98 		return -EINVAL;
99 	/*
100 	 * f is encoded on two bits.
101 	 * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
102 	 * ALT1
103 	 * This is racy because both registers can't be updated at the same time
104 	 * but it doesn't matter much for now.
105 	 */
106 	offset = pin->pin;
107 	regoff = info->mscc_gpios[MSCC_GPIO_ALT0];
108 	if (offset >= 32) {
109 		offset = offset % 32;
110 		regoff = info->mscc_gpios[MSCC_GPIO_ALT1];
111 	}
112 
113 	if (f & BIT(0))
114 		mscc_setbits(offset, info->regs + regoff);
115 	else
116 		mscc_clrbits(offset, info->regs + regoff);
117 
118 	if (f & BIT(1))
119 		mscc_setbits(offset, info->regs + regoff + 4);
120 	else
121 		mscc_clrbits(offset, info->regs + regoff + 4);
122 
123 	return 0;
124 }
125 
mscc_pctl_get_groups_count(struct udevice * dev)126 static int mscc_pctl_get_groups_count(struct udevice *dev)
127 {
128 	struct mscc_pinctrl *info = dev_get_priv(dev);
129 
130 	return info->num_pins;
131 }
132 
mscc_pctl_get_group_name(struct udevice * dev,unsigned int group)133 static const char *mscc_pctl_get_group_name(struct udevice *dev,
134 					    unsigned int group)
135 {
136 	struct mscc_pinctrl *info = dev_get_priv(dev);
137 
138 	return info->mscc_pins[group].name;
139 }
140 
mscc_create_group_func_map(struct udevice * dev,struct mscc_pinctrl * info)141 static int mscc_create_group_func_map(struct udevice *dev,
142 				      struct mscc_pinctrl *info)
143 {
144 	u16 pins[info->num_pins];
145 	int f, npins, i;
146 
147 	for (f = 0; f < info->num_func; f++) {
148 		for (npins = 0, i = 0; i < info->num_pins; i++) {
149 			if (mscc_pin_function_idx(i, f, info->mscc_pins) >= 0)
150 				pins[npins++] = i;
151 		}
152 
153 		info->func[f].ngroups = npins;
154 		info->func[f].groups = devm_kzalloc(dev, npins * sizeof(char *),
155 						    GFP_KERNEL);
156 		if (!info->func[f].groups)
157 			return -ENOMEM;
158 
159 		for (i = 0; i < npins; i++)
160 			info->func[f].groups[i] = info->mscc_pins[pins[i]].name;
161 	}
162 
163 	return 0;
164 }
165 
mscc_pinctrl_register(struct udevice * dev,struct mscc_pinctrl * info)166 static int mscc_pinctrl_register(struct udevice *dev, struct mscc_pinctrl *info)
167 {
168 	int ret;
169 
170 	ret = mscc_create_group_func_map(dev, info);
171 	if (ret) {
172 		dev_err(dev, "Unable to create group func map.\n");
173 		return ret;
174 	}
175 
176 	return 0;
177 }
178 
mscc_gpio_get(struct udevice * dev,unsigned int offset)179 static int mscc_gpio_get(struct udevice *dev, unsigned int offset)
180 {
181 	struct mscc_pinctrl *info = dev_get_priv(dev->parent);
182 	unsigned int val;
183 
184 	if (mscc_readl(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]) &
185 	    BIT(offset % 32))
186 		val = mscc_readl(offset,
187 				 info->regs + info->mscc_gpios[MSCC_GPIO_OUT]);
188 	else
189 		val = mscc_readl(offset,
190 				 info->regs + info->mscc_gpios[MSCC_GPIO_IN]);
191 
192 	return !!(val & BIT(offset % 32));
193 }
194 
mscc_gpio_set(struct udevice * dev,unsigned int offset,int value)195 static int mscc_gpio_set(struct udevice *dev, unsigned int offset, int value)
196 {
197 	struct mscc_pinctrl *info = dev_get_priv(dev->parent);
198 
199 	if (value)
200 		mscc_writel(offset,
201 			    info->regs + info->mscc_gpios[MSCC_GPIO_OUT_SET]);
202 	else
203 		mscc_writel(offset,
204 			    info->regs + info->mscc_gpios[MSCC_GPIO_OUT_CLR]);
205 
206 	return 0;
207 }
208 
mscc_gpio_get_direction(struct udevice * dev,unsigned int offset)209 static int mscc_gpio_get_direction(struct udevice *dev, unsigned int offset)
210 {
211 	struct mscc_pinctrl *info = dev_get_priv(dev->parent);
212 	unsigned int val;
213 
214 	val = mscc_readl(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]);
215 
216 	return (val & BIT(offset % 32)) ? GPIOF_OUTPUT : GPIOF_INPUT;
217 }
218 
mscc_gpio_direction_input(struct udevice * dev,unsigned int offset)219 static int mscc_gpio_direction_input(struct udevice *dev, unsigned int offset)
220 {
221 	struct mscc_pinctrl *info = dev_get_priv(dev->parent);
222 
223 	mscc_clrbits(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]);
224 
225 	return 0;
226 }
227 
mscc_gpio_direction_output(struct udevice * dev,unsigned int offset,int value)228 static int mscc_gpio_direction_output(struct udevice *dev,
229 				      unsigned int offset, int value)
230 {
231 	struct mscc_pinctrl *info = dev_get_priv(dev->parent);
232 
233 	mscc_setbits(offset, info->regs + info->mscc_gpios[MSCC_GPIO_OE]);
234 
235 	return mscc_gpio_set(dev, offset, value);
236 }
237 
238 const struct dm_gpio_ops mscc_gpio_ops = {
239 	.set_value = mscc_gpio_set,
240 	.get_value = mscc_gpio_get,
241 	.get_function = mscc_gpio_get_direction,
242 	.direction_input = mscc_gpio_direction_input,
243 	.direction_output = mscc_gpio_direction_output,
244 };
245 
246 const struct pinctrl_ops mscc_pinctrl_ops = {
247 	.get_pins_count = mscc_pctl_get_groups_count,
248 	.get_pin_name = mscc_pctl_get_group_name,
249 	.get_functions_count = mscc_get_functions_count,
250 	.get_function_name = mscc_get_function_name,
251 	.pinmux_set = mscc_pinmux_set_mux,
252 	.set_state = pinctrl_generic_set_state,
253 };
254 
mscc_pinctrl_probe(struct udevice * dev,int num_func,const struct mscc_pin_data * mscc_pins,int num_pins,char * const * function_names,const unsigned long * mscc_gpios)255 int mscc_pinctrl_probe(struct udevice *dev, int num_func,
256 		       const struct mscc_pin_data *mscc_pins, int num_pins,
257 		       char * const *function_names,
258 		       const unsigned long *mscc_gpios)
259 {
260 	struct mscc_pinctrl *priv = dev_get_priv(dev);
261 	int ret;
262 
263 	priv->regs = dev_remap_addr(dev);
264 	if (!priv->regs)
265 		return -EINVAL;
266 
267 	priv->func = devm_kzalloc(dev, num_func * sizeof(struct mscc_pmx_func),
268 				  GFP_KERNEL);
269 	priv->num_func = num_func;
270 	priv->mscc_pins = mscc_pins;
271 	priv->num_pins = num_pins;
272 	priv->function_names = function_names;
273 	priv->mscc_gpios = mscc_gpios;
274 	ret = mscc_pinctrl_register(dev, priv);
275 
276 	return ret;
277 }
278