1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <common.h>
4 #include <dm.h>
5 #include <errno.h>
6 #include <asm/io.h>
7 #include <asm/arch/pinctrl.h>
8 #include <asm/arch/scu_ast2400.h>
9 #include <dm/pinctrl.h>
10 #include "pinctrl-aspeed.h"
11 /*
12 * This driver works with very simple configuration that has the same name
13 * for group and function. This way it is compatible with the Linux Kernel
14 * driver.
15 */
16
17 struct ast2400_pinctrl_priv {
18 struct ast2400_scu *scu;
19 };
20
ast2400_pinctrl_probe(struct udevice * dev)21 static int ast2400_pinctrl_probe(struct udevice *dev)
22 {
23 struct ast2400_pinctrl_priv *priv = dev_get_priv(dev);
24 struct udevice *clk_dev;
25 int ret = 0;
26
27 /* find SCU base address from clock device */
28 ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(aspeed_scu),
29 &clk_dev);
30 if (ret) {
31 debug("clock device not found\n");
32 return ret;
33 }
34
35 priv->scu = devfdt_get_addr_ptr(clk_dev);
36 if (IS_ERR(priv->scu)) {
37 debug("%s(): can't get SCU\n", __func__);
38 return PTR_ERR(priv->scu);
39 }
40
41 return 0;
42 }
43
44 static struct aspeed_sig_desc mac1_link[] = {
45 { 0x80, BIT(0), 0 },
46 };
47
48 static struct aspeed_sig_desc mac2_link[] = {
49 { 0x80, BIT(1), 0 },
50 };
51
52 static struct aspeed_sig_desc mdio1_link[] = {
53 { 0x88, BIT(31) | BIT(30), 0 },
54 };
55
56 static struct aspeed_sig_desc mdio2_link[] = {
57 { 0x90, BIT(2), 0 },
58 };
59
60 static struct aspeed_sig_desc i2c3_link[] = {
61 { 0x90, BIT(16), 0 },
62 };
63
64 static struct aspeed_sig_desc i2c4_link[] = {
65 { 0x90, BIT(17), 0 },
66 };
67
68 static struct aspeed_sig_desc i2c5_link[] = {
69 { 0x90, BIT(18), 0 },
70 };
71
72 static struct aspeed_sig_desc i2c6_link[] = {
73 { 0x90, BIT(19), 0 },
74 };
75
76 static struct aspeed_sig_desc i2c7_link[] = {
77 { 0x90, BIT(20), 0 },
78 };
79
80 static struct aspeed_sig_desc i2c8_link[] = {
81 { 0x90, BIT(21), 0 },
82 };
83
84 static struct aspeed_sig_desc i2c9_link[] = {
85 { 0x90, BIT(22), 0 },
86 };
87
88 static struct aspeed_sig_desc i2c10_link[] = {
89 { 0x90, BIT(23), 0 },
90 { 0x90, BIT(0), 1 },
91 };
92
93 static struct aspeed_sig_desc i2c11_link[] = {
94 { 0x90, BIT(24), 0 },
95 { 0x90, BIT(0), 1 },
96 };
97
98 static struct aspeed_sig_desc i2c12_link[] = {
99 { 0x90, BIT(25), 0 },
100 { 0x90, BIT(0), 1 },
101 };
102
103 static struct aspeed_sig_desc i2c13_link[] = {
104 { 0x90, BIT(26), 0 },
105 { 0x90, BIT(0), 1 },
106 };
107
108 static struct aspeed_sig_desc i2c14_link[] = {
109 { 0x90, BIT(27), 0 },
110 };
111
112 static struct aspeed_sig_desc sdio1_link[] = {
113 { 0x90, BIT(0), 0 },
114 };
115
116 static struct aspeed_sig_desc sdio2_link[] = {
117 { 0x90, BIT(1), 0 },
118 };
119
120 static struct aspeed_sig_desc spi1cs1_link[] = {
121 { 0x80, BIT(15), 0},
122 };
123
124 static struct aspeed_sig_desc spi1_link[] = {
125 { 0x70, BIT(12), 0},
126 };
127
128 static struct aspeed_sig_desc txd3_link[] = {
129 { 0x80, BIT(22), 0},
130 };
131
132 static struct aspeed_sig_desc rxd3_link[] = {
133 { 0x80, BIT(23), 0},
134 };
135
136 static struct aspeed_sig_desc rgmii1_link[] = {
137 { 0xa0, GENMASK(17, 12) | GENMASK(5, 0), 1 },
138 };
139
140 static struct aspeed_sig_desc rgmii2_link[] = {
141 { 0xa0, GENMASK(23, 18) | GENMASK(11, 6), 1 },
142 };
143
144 static const struct aspeed_group_config ast2400_groups[] = {
145 { "MAC1LINK", 1, mac1_link },
146 { "MAC2LINK", 1, mac2_link },
147 { "MDIO1", 1, mdio1_link },
148 { "MDIO2", 1, mdio2_link },
149 { "I2C3", 1, i2c3_link },
150 { "I2C4", 1, i2c4_link },
151 { "I2C5", 1, i2c5_link },
152 { "I2C6", 1, i2c6_link },
153 { "I2C7", 1, i2c7_link },
154 { "I2C8", 1, i2c8_link },
155 { "I2C9", 1, i2c9_link },
156 { "I2C10", 2, i2c10_link },
157 { "I2C11", 2, i2c11_link },
158 { "I2C12", 2, i2c12_link },
159 { "I2C13", 2, i2c13_link },
160 { "I2C14", 1, i2c14_link },
161 { "SD2", 1, sdio2_link },
162 { "SD1", 1, sdio1_link },
163 { "SPI1", 1, spi1_link},
164 { "SPI1CS1", 1, spi1cs1_link},
165 { "TXD3", 1, txd3_link },
166 { "RXD3", 1, rxd3_link },
167 { "RGMII1", 1, rgmii1_link },
168 { "RGMII2", 1, rgmii2_link },
169 };
170
ast2400_pinctrl_get_groups_count(struct udevice * dev)171 static int ast2400_pinctrl_get_groups_count(struct udevice *dev)
172 {
173 debug("PINCTRL: get_(functions/groups)_count\n");
174
175 return ARRAY_SIZE(ast2400_groups);
176 }
177
ast2400_pinctrl_get_group_name(struct udevice * dev,unsigned selector)178 static const char *ast2400_pinctrl_get_group_name(struct udevice *dev,
179 unsigned selector)
180 {
181 debug("PINCTRL: get_(function/group)_name %u\n", selector);
182
183 return ast2400_groups[selector].group_name;
184 }
185
ast2400_pinctrl_group_set(struct udevice * dev,unsigned selector,unsigned func_selector)186 static int ast2400_pinctrl_group_set(struct udevice *dev, unsigned selector,
187 unsigned func_selector)
188 {
189 struct ast2400_pinctrl_priv *priv = dev_get_priv(dev);
190 const struct aspeed_group_config *config;
191 const struct aspeed_sig_desc *descs;
192 u32 *ctrl_reg = (u32*)priv->scu;
193 int i;
194
195 debug("PINCTRL: group_set <%u, %u> \n", selector, func_selector);
196 if (selector >= ARRAY_SIZE(ast2400_groups))
197 return -EINVAL;
198
199 config = &ast2400_groups[selector];
200
201 for( i = 0; i < config->ndescs; i++) {
202 descs = &config->descs[i];
203 if(descs->clr) {
204 clrbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
205 } else {
206 setbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
207 }
208 }
209
210 return 0;
211 }
212
213 static struct pinctrl_ops ast2400_pinctrl_ops = {
214 .set_state = pinctrl_generic_set_state,
215 .get_groups_count = ast2400_pinctrl_get_groups_count,
216 .get_group_name = ast2400_pinctrl_get_group_name,
217 .get_functions_count = ast2400_pinctrl_get_groups_count,
218 .get_function_name = ast2400_pinctrl_get_group_name,
219 .pinmux_group_set = ast2400_pinctrl_group_set,
220 };
221
222 static const struct udevice_id ast2400_pinctrl_ids[] = {
223 { .compatible = "aspeed,g4-pinctrl" },
224 { }
225 };
226
227 U_BOOT_DRIVER(pinctrl_aspeed) = {
228 .name = "aspeed_ast2400_pinctrl",
229 .id = UCLASS_PINCTRL,
230 .of_match = ast2400_pinctrl_ids,
231 .priv_auto_alloc_size = sizeof(struct ast2400_pinctrl_priv),
232 .ops = &ast2400_pinctrl_ops,
233 .probe = ast2400_pinctrl_probe,
234 };
235