blob: 3e98a01bad43c0c64997a20eb2a57820f84a0074 [file] [log] [blame]
developer6d1a6302022-05-20 11:22:49 +08001// 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
51struct mt7621_pinctrl_priv {
52 struct mtmips_pinctrl_priv mp;
53};
54
55#if CONFIG_IS_ENABLED(PINMUX)
56static const struct mtmips_pmx_func esw_int_grp[] = {
57 FUNC("gpio", 1),
58 FUNC("esw int", 0),
59};
60
61static const struct mtmips_pmx_func sdxc_grp[] = {
62 FUNC("nand", 2),
63 FUNC("gpio", 1),
64 FUNC("sdxc", 0),
65};
66
67static const struct mtmips_pmx_func spi_grp[] = {
68 FUNC("nand", 2),
69 FUNC("gpio", 1),
70 FUNC("spi", 0),
71};
72
73static const struct mtmips_pmx_func rgmii2_grp[] = {
74 FUNC("gpio", 1),
75 FUNC("rgmii", 0),
76};
77
78static const struct mtmips_pmx_func rgmii1_grp[] = {
79 FUNC("gpio", 1),
80 FUNC("rgmii", 0),
81};
82
83static const struct mtmips_pmx_func mdio_grp[] = {
84 FUNC("gpio", 1),
85 FUNC("mdio", 0),
86};
87
88static const struct mtmips_pmx_func perst_grp[] = {
89 FUNC("refclk", 2),
90 FUNC("gpio", 1),
91 FUNC("pcie reset", 0),
92};
93
94static const struct mtmips_pmx_func wdt_grp[] = {
95 FUNC("refclk", 2),
96 FUNC("gpio", 1),
97 FUNC("wdt rst", 0),
98};
99
100static const struct mtmips_pmx_func jtag_grp[] = {
101 FUNC("gpio", 1),
102 FUNC("jtag", 0),
103};
104
105static 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
112static 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
119static const struct mtmips_pmx_func i2c_grp[] = {
120 FUNC("gpio", 1),
121 FUNC("i2c", 0),
122};
123
124static const struct mtmips_pmx_func uart1_grp[] = {
125 FUNC("gpio", 1),
126 FUNC("uart", 0),
127};
128
129static const struct mtmips_pmx_func gpio0_grp[] = {
130 FUNC("gpio", 0),
131};
132
133static 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
163static int mt7621_get_groups_count(struct udevice *dev)
164{
165 return ARRAY_SIZE(mt7621_pmx_data);
166}
167
168static 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)
176static 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
186static const u32 mt7621_pconf_drv_strength_tbl[] = {2, 4, 6, 8};
187
188static 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
252static 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
265static 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
277static 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
293static const struct udevice_id mt7621_pinctrl_ids[] = {
294 { .compatible = "mediatek,mt7621-pinctrl" },
295 { }
296};
297
298U_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};