1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2022 MediaTek Inc. All rights reserved.
4 *
5 * Author: Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8 #include <dm.h>
9 #include <dm/pinctrl.h>
10 #include <dm/device_compat.h>
11 #include <linux/bitops.h>
12 #include <linux/io.h>
13
14 #include "pinctrl-mtmips-common.h"
15
16 #define SYSC_MAP_SIZE 0x100
17
18 #define PAD_UART1_GPIO0_OFS 0x00
19 #define PAD_UART3_I2C_OFS 0x04
20 #define PAD_UART2_JTAG_OFS 0x08
21 #define PAD_PERST_WDT_OFS 0x0c
22 #define PAD_RGMII2_MDIO_OFS 0x10
23 #define PAD_SDXC_SPI_OFS 0x14
24 #define GPIOMODE_OFS 0x18
25 #define PAD_BOPT_ESWINT_OFS 0x28
26
27 #define ESWINT_SHIFT 20
28 #define SDXC_SHIFT 18
29 #define SPI_SHIFT 16
30 #define RGMII2_SHIFT 15
31 #define RGMII1_SHIFT 14
32 #define MDIO_SHIFT 12
33 #define PERST_SHIFT 10
34 #define WDT_SHIFT 8
35 #define JTAG_SHIFT 7
36 #define UART2_SHIFT 5
37 #define UART3_SHIFT 3
38 #define I2C_SHIFT 2
39 #define UART1_SHIFT 1
40 #define GPIO0_SHIFT 0 /* Dummy */
41
42 #define GM4_MASK 3
43
44 #define E4_E2_M 0x03
45 #define E4_E2_S 4
46 #define PULL_UP BIT(3)
47 #define PULL_DOWN BIT(2)
48 #define SMT BIT(1)
49 #define SR BIT(0)
50
51 struct mt7621_pinctrl_priv {
52 struct mtmips_pinctrl_priv mp;
53 };
54
55 #if CONFIG_IS_ENABLED(PINMUX)
56 static const struct mtmips_pmx_func esw_int_grp[] = {
57 FUNC("gpio", 1),
58 FUNC("esw int", 0),
59 };
60
61 static const struct mtmips_pmx_func sdxc_grp[] = {
62 FUNC("nand", 2),
63 FUNC("gpio", 1),
64 FUNC("sdxc", 0),
65 };
66
67 static const struct mtmips_pmx_func spi_grp[] = {
68 FUNC("nand", 2),
69 FUNC("gpio", 1),
70 FUNC("spi", 0),
71 };
72
73 static const struct mtmips_pmx_func rgmii2_grp[] = {
74 FUNC("gpio", 1),
75 FUNC("rgmii", 0),
76 };
77
78 static const struct mtmips_pmx_func rgmii1_grp[] = {
79 FUNC("gpio", 1),
80 FUNC("rgmii", 0),
81 };
82
83 static const struct mtmips_pmx_func mdio_grp[] = {
84 FUNC("gpio", 1),
85 FUNC("mdio", 0),
86 };
87
88 static const struct mtmips_pmx_func perst_grp[] = {
89 FUNC("refclk", 2),
90 FUNC("gpio", 1),
91 FUNC("pcie reset", 0),
92 };
93
94 static const struct mtmips_pmx_func wdt_grp[] = {
95 FUNC("refclk", 2),
96 FUNC("gpio", 1),
97 FUNC("wdt rst", 0),
98 };
99
100 static const struct mtmips_pmx_func jtag_grp[] = {
101 FUNC("gpio", 1),
102 FUNC("jtag", 0),
103 };
104
105 static const struct mtmips_pmx_func uart2_grp[] = {
106 FUNC("spdif", 3),
107 FUNC("pcm", 2),
108 FUNC("gpio", 1),
109 FUNC("uart", 0),
110 };
111
112 static const struct mtmips_pmx_func uart3_grp[] = {
113 FUNC("spdif", 3),
114 FUNC("i2s", 2),
115 FUNC("gpio", 1),
116 FUNC("uart", 0),
117 };
118
119 static const struct mtmips_pmx_func i2c_grp[] = {
120 FUNC("gpio", 1),
121 FUNC("i2c", 0),
122 };
123
124 static const struct mtmips_pmx_func uart1_grp[] = {
125 FUNC("gpio", 1),
126 FUNC("uart", 0),
127 };
128
129 static const struct mtmips_pmx_func gpio0_grp[] = {
130 FUNC("gpio", 0),
131 };
132
133 static const struct mtmips_pmx_group mt7621_pmx_data[] = {
134 GRP_PCONF("esw int", esw_int_grp, GPIOMODE_OFS, ESWINT_SHIFT, 1,
135 PAD_BOPT_ESWINT_OFS, 0),
136 GRP_PCONF("sdxc", sdxc_grp, GPIOMODE_OFS, SDXC_SHIFT, GM4_MASK,
137 PAD_SDXC_SPI_OFS, 16),
138 GRP_PCONF("spi", spi_grp, GPIOMODE_OFS, SPI_SHIFT, GM4_MASK,
139 PAD_SDXC_SPI_OFS, 0),
140 GRP_PCONF("rgmii2", rgmii2_grp, GPIOMODE_OFS, RGMII2_SHIFT, 1,
141 PAD_RGMII2_MDIO_OFS, 16),
142 GRP("rgmii1", rgmii1_grp, GPIOMODE_OFS, RGMII1_SHIFT, 1),
143 GRP_PCONF("mdio", mdio_grp, GPIOMODE_OFS, MDIO_SHIFT, GM4_MASK,
144 PAD_RGMII2_MDIO_OFS, 0),
145 GRP_PCONF("pcie reset", perst_grp, GPIOMODE_OFS, PERST_SHIFT, GM4_MASK,
146 PAD_PERST_WDT_OFS, 16),
147 GRP_PCONF("wdt", wdt_grp, GPIOMODE_OFS, WDT_SHIFT, GM4_MASK,
148 PAD_PERST_WDT_OFS, 0),
149 GRP_PCONF("jtag", jtag_grp, GPIOMODE_OFS, JTAG_SHIFT, 1,
150 PAD_UART2_JTAG_OFS, 16),
151 GRP_PCONF("uart2", uart2_grp, GPIOMODE_OFS, UART2_SHIFT, GM4_MASK,
152 PAD_UART2_JTAG_OFS, 0),
153 GRP_PCONF("uart3", uart3_grp, GPIOMODE_OFS, UART3_SHIFT, GM4_MASK,
154 PAD_UART3_I2C_OFS, 16),
155 GRP_PCONF("i2c", i2c_grp, GPIOMODE_OFS, I2C_SHIFT, 1,
156 PAD_UART3_I2C_OFS, 0),
157 GRP_PCONF("uart1", uart1_grp, GPIOMODE_OFS, UART1_SHIFT, 1,
158 PAD_UART1_GPIO0_OFS, 16),
159 GRP_PCONF("gpio0", gpio0_grp, GPIOMODE_OFS, GPIO0_SHIFT, 1,
160 PAD_UART1_GPIO0_OFS, 0),
161 };
162
mt7621_get_groups_count(struct udevice * dev)163 static int mt7621_get_groups_count(struct udevice *dev)
164 {
165 return ARRAY_SIZE(mt7621_pmx_data);
166 }
167
mt7621_get_group_name(struct udevice * dev,unsigned int selector)168 static const char *mt7621_get_group_name(struct udevice *dev,
169 unsigned int selector)
170 {
171 return mt7621_pmx_data[selector].name;
172 }
173 #endif /* CONFIG_IS_ENABLED(PINMUX) */
174
175 #if CONFIG_IS_ENABLED(PINCONF)
176 static const struct pinconf_param mt7621_conf_params[] = {
177 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
178 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
179 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
180 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
181 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
182 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
183 { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
184 };
185
186 static const u32 mt7621_pconf_drv_strength_tbl[] = {2, 4, 6, 8};
187
mt7621_pinconf_group_set(struct udevice * dev,unsigned int group_selector,unsigned int param,unsigned int arg)188 static int mt7621_pinconf_group_set(struct udevice *dev,
189 unsigned int group_selector,
190 unsigned int param, unsigned int arg)
191 {
192 struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
193 const struct mtmips_pmx_group *grp = &mt7621_pmx_data[group_selector];
194 u32 clr = 0, set = 0;
195 int i;
196
197 if (!grp->pconf_avail)
198 return 0;
199
200 switch (param) {
201 case PIN_CONFIG_BIAS_DISABLE:
202 clr = PULL_UP | PULL_DOWN;
203 break;
204
205 case PIN_CONFIG_BIAS_PULL_UP:
206 clr = PULL_DOWN;
207 set = PULL_UP;
208 break;
209
210 case PIN_CONFIG_BIAS_PULL_DOWN:
211 clr = PULL_UP;
212 set = PULL_DOWN;
213 break;
214
215 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
216 if (arg)
217 set = SMT;
218 else
219 clr = SMT;
220 break;
221
222 case PIN_CONFIG_DRIVE_STRENGTH:
223 for (i = 0; i < ARRAY_SIZE(mt7621_pconf_drv_strength_tbl); i++)
224 if (mt7621_pconf_drv_strength_tbl[i] == arg)
225 break;
226
227 if (i >= ARRAY_SIZE(mt7621_pconf_drv_strength_tbl))
228 return -EINVAL;
229
230 clr = E4_E2_M << E4_E2_S;
231 set = i << E4_E2_S;
232 break;
233
234 case PIN_CONFIG_SLEW_RATE:
235 if (arg)
236 set = SR;
237 else
238 clr = SR;
239 break;
240
241 default:
242 return -EINVAL;
243 }
244
245 mtmips_pinctrl_reg_set(&priv->mp, grp->pconf_reg, grp->pconf_shift,
246 clr, set);
247
248 return 0;
249 }
250 #endif
251
mt7621_pinctrl_probe(struct udevice * dev)252 static int mt7621_pinctrl_probe(struct udevice *dev)
253 {
254 struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
255 int ret = 0;
256
257 #if CONFIG_IS_ENABLED(PINMUX)
258 ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7621_pmx_data),
259 mt7621_pmx_data);
260 #endif /* CONFIG_IS_ENABLED(PINMUX) */
261
262 return ret;
263 }
264
mt7621_pinctrl_of_to_plat(struct udevice * dev)265 static int mt7621_pinctrl_of_to_plat(struct udevice *dev)
266 {
267 struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
268
269 priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0);
270
271 if (!priv->mp.base)
272 return -EINVAL;
273
274 return 0;
275 }
276
277 static const struct pinctrl_ops mt7621_pinctrl_ops = {
278 #if CONFIG_IS_ENABLED(PINMUX)
279 .get_groups_count = mt7621_get_groups_count,
280 .get_group_name = mt7621_get_group_name,
281 .get_functions_count = mtmips_get_functions_count,
282 .get_function_name = mtmips_get_function_name,
283 .pinmux_group_set = mtmips_pinmux_group_set,
284 #endif /* CONFIG_IS_ENABLED(PINMUX) */
285 #if CONFIG_IS_ENABLED(PINCONF)
286 .pinconf_num_params = ARRAY_SIZE(mt7621_conf_params),
287 .pinconf_params = mt7621_conf_params,
288 .pinconf_group_set = mt7621_pinconf_group_set,
289 #endif /* CONFIG_IS_ENABLED(PINCONF) */
290 .set_state = pinctrl_generic_set_state,
291 };
292
293 static const struct udevice_id mt7621_pinctrl_ids[] = {
294 { .compatible = "mediatek,mt7621-pinctrl" },
295 { }
296 };
297
298 U_BOOT_DRIVER(mt7621_pinctrl) = {
299 .name = "mt7621-pinctrl",
300 .id = UCLASS_PINCTRL,
301 .of_match = mt7621_pinctrl_ids,
302 .of_to_plat = mt7621_pinctrl_of_to_plat,
303 .ops = &mt7621_pinctrl_ops,
304 .probe = mt7621_pinctrl_probe,
305 .priv_auto = sizeof(struct mt7621_pinctrl_priv),
306 };
307