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