1 /*
2  * Copyright (C) 2015-2016 Socionext Inc.
3  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <linux/io.h>
10 #include <linux/err.h>
11 #include <linux/sizes.h>
12 #include <dm/device.h>
13 #include <dm/pinctrl.h>
14 
15 #include "pinctrl-uniphier.h"
16 
17 #define UNIPHIER_PINCTRL_PINMUX_BASE	0x1000
18 #define UNIPHIER_PINCTRL_LOAD_PINMUX	0x1700
19 #define UNIPHIER_PINCTRL_PUPDCTRL_BASE	0x1a00
20 #define UNIPHIER_PINCTRL_IECTRL		0x1d00
21 
22 static const char *uniphier_pinctrl_dummy_name = "_dummy";
23 
24 static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
25 {
26 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
27 
28 	return priv->socdata->groups_count;
29 }
30 
31 static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
32 						   unsigned selector)
33 {
34 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
35 
36 	if (!priv->socdata->groups[selector].name)
37 		return uniphier_pinctrl_dummy_name;
38 
39 	return priv->socdata->groups[selector].name;
40 }
41 
42 static int uniphier_pinmux_get_functions_count(struct udevice *dev)
43 {
44 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
45 
46 	return priv->socdata->functions_count;
47 }
48 
49 static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
50 						     unsigned selector)
51 {
52 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
53 
54 	if (!priv->socdata->functions[selector])
55 		return uniphier_pinctrl_dummy_name;
56 
57 	return priv->socdata->functions[selector];
58 }
59 
60 static int uniphier_pinconf_input_enable_perpin(struct udevice *dev,
61 						unsigned int pin, int enable)
62 {
63 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
64 	unsigned reg;
65 	u32 mask, tmp;
66 
67 	reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4;
68 	mask = BIT(pin % 32);
69 
70 	tmp = readl(priv->base + reg);
71 	if (enable)
72 		tmp |= mask;
73 	else
74 		tmp &= ~mask;
75 	writel(tmp, priv->base + reg);
76 
77 	return 0;
78 }
79 
80 static int uniphier_pinconf_input_enable_legacy(struct udevice *dev,
81 						unsigned int pin, int enable)
82 {
83 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
84 	int pins_count = priv->socdata->pins_count;
85 	const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
86 	int i;
87 
88 	/*
89 	 * Multiple pins share one input enable, per-pin disabling is
90 	 * impossible.
91 	 */
92 	if (!enable)
93 		return -EINVAL;
94 
95 	for (i = 0; i < pins_count; i++) {
96 		if (pins[i].number == pin) {
97 			unsigned int iectrl;
98 			u32 tmp;
99 
100 			iectrl = uniphier_pin_get_iectrl(pins[i].data);
101 			tmp = readl(priv->base + UNIPHIER_PINCTRL_IECTRL);
102 			tmp |= 1 << iectrl;
103 			writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL);
104 		}
105 	}
106 
107 	return 0;
108 }
109 
110 static int uniphier_pinconf_input_enable(struct udevice *dev,
111 					 unsigned int pin, int enable)
112 {
113 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
114 
115 	if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
116 		return uniphier_pinconf_input_enable_perpin(dev, pin, enable);
117 	else
118 		return uniphier_pinconf_input_enable_legacy(dev, pin, enable);
119 }
120 
121 #if CONFIG_IS_ENABLED(PINCONF)
122 
123 static const struct pinconf_param uniphier_pinconf_params[] = {
124 	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
125 	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
126 	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
127 	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
128 	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
129 	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
130 };
131 
132 static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
133 				     unsigned int param, unsigned int arg)
134 {
135 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
136 	unsigned int enable = 1;
137 	unsigned int reg;
138 	u32 mask, tmp;
139 
140 	if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE))
141 		return -ENOTSUPP;
142 
143 	switch (param) {
144 	case PIN_CONFIG_BIAS_DISABLE:
145 		enable = 0;
146 		break;
147 	case PIN_CONFIG_BIAS_PULL_UP:
148 	case PIN_CONFIG_BIAS_PULL_DOWN:
149 		if (arg == 0)	/* total bias is not supported */
150 			return -EINVAL;
151 		break;
152 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
153 		if (arg == 0)	/* configuration ignored */
154 			return 0;
155 	default:
156 		BUG();
157 	}
158 
159 	reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4;
160 	mask = BIT(pin % 32);
161 
162 	tmp = readl(priv->base + reg);
163 	if (enable)
164 		tmp |= mask;
165 	else
166 		tmp &= ~mask;
167 	writel(tmp, priv->base + reg);
168 
169 	return 0;
170 }
171 
172 static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
173 				    unsigned int param, unsigned int arg)
174 {
175 	int ret;
176 
177 	switch (param) {
178 	case PIN_CONFIG_BIAS_DISABLE:
179 	case PIN_CONFIG_BIAS_PULL_UP:
180 	case PIN_CONFIG_BIAS_PULL_DOWN:
181 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
182 		ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
183 		break;
184 	case PIN_CONFIG_INPUT_ENABLE:
185 		ret = uniphier_pinconf_input_enable(dev, pin, arg);
186 		break;
187 	default:
188 		printf("unsupported configuration parameter %u\n", param);
189 		return -EINVAL;
190 	}
191 
192 	return ret;
193 }
194 
195 static int uniphier_pinconf_group_set(struct udevice *dev,
196 				      unsigned int group_selector,
197 				      unsigned int param, unsigned int arg)
198 {
199 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
200 	const struct uniphier_pinctrl_group *grp =
201 					&priv->socdata->groups[group_selector];
202 	int i, ret;
203 
204 	for (i = 0; i < grp->num_pins; i++) {
205 		ret = uniphier_pinconf_set_one(dev, grp->pins[i], param, arg);
206 		if (ret)
207 			return ret;
208 	}
209 
210 	return 0;
211 }
212 
213 #endif /* CONFIG_IS_ENABLED(PINCONF) */
214 
215 static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
216 				    int muxval)
217 {
218 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
219 	unsigned reg, reg_end, shift, mask;
220 	unsigned mux_bits = 8;
221 	unsigned reg_stride = 4;
222 	bool load_pinctrl = false;
223 	u32 tmp;
224 
225 	/* some pins need input-enabling */
226 	uniphier_pinconf_input_enable(dev, pin, 1);
227 
228 	if (muxval < 0)
229 		return;		/* dedicated pin; nothing to do for pin-mux */
230 
231 	if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_MUX_4BIT)
232 		mux_bits = 4;
233 
234 	if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
235 		/*
236 		 *  Mode       offset        bit
237 		 *  Normal     4 * n     shift+3:shift
238 		 *  Debug      4 * n     shift+7:shift+4
239 		 */
240 		mux_bits /= 2;
241 		reg_stride = 8;
242 		load_pinctrl = true;
243 	}
244 
245 	reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
246 	reg_end = reg + reg_stride;
247 	shift = pin * mux_bits % 32;
248 	mask = (1U << mux_bits) - 1;
249 
250 	/*
251 	 * If reg_stride is greater than 4, the MSB of each pinsel shall be
252 	 * stored in the offset+4.
253 	 */
254 	for (; reg < reg_end; reg += 4) {
255 		tmp = readl(priv->base + reg);
256 		tmp &= ~(mask << shift);
257 		tmp |= (mask & muxval) << shift;
258 		writel(tmp, priv->base + reg);
259 
260 		muxval >>= mux_bits;
261 	}
262 
263 	if (load_pinctrl)
264 		writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX);
265 }
266 
267 static int uniphier_pinmux_group_set(struct udevice *dev,
268 				     unsigned group_selector,
269 				     unsigned func_selector)
270 {
271 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
272 	const struct uniphier_pinctrl_group *grp =
273 					&priv->socdata->groups[group_selector];
274 	int i;
275 
276 	for (i = 0; i < grp->num_pins; i++)
277 		uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]);
278 
279 	return 0;
280 }
281 
282 const struct pinctrl_ops uniphier_pinctrl_ops = {
283 	.get_groups_count = uniphier_pinctrl_get_groups_count,
284 	.get_group_name = uniphier_pinctrl_get_group_name,
285 	.get_functions_count = uniphier_pinmux_get_functions_count,
286 	.get_function_name = uniphier_pinmux_get_function_name,
287 	.pinmux_group_set = uniphier_pinmux_group_set,
288 #if CONFIG_IS_ENABLED(PINCONF)
289 	.pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
290 	.pinconf_params = uniphier_pinconf_params,
291 	.pinconf_group_set = uniphier_pinconf_group_set,
292 #endif
293 	.set_state = pinctrl_generic_set_state,
294 };
295 
296 int uniphier_pinctrl_probe(struct udevice *dev,
297 			   struct uniphier_pinctrl_socdata *socdata)
298 {
299 	struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
300 	fdt_addr_t addr;
301 
302 	addr = dev_get_addr(dev->parent);
303 	if (addr == FDT_ADDR_T_NONE)
304 		return -EINVAL;
305 
306 	priv->base = devm_ioremap(dev, addr, SZ_4K);
307 	if (!priv->base)
308 		return -ENOMEM;
309 
310 	priv->socdata = socdata;
311 
312 	return 0;
313 }
314