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 
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 const struct aspeed_group_config ast2400_groups[] = {
129 	{ "MAC1LINK", 1, mac1_link },
130 	{ "MAC2LINK", 1, mac2_link },
131 	{ "MDIO1", 1, mdio1_link },
132 	{ "MDIO2", 1, mdio2_link },
133 	{ "I2C3", 1, i2c3_link },
134 	{ "I2C4", 1, i2c4_link },
135 	{ "I2C5", 1, i2c5_link },
136 	{ "I2C6", 1, i2c6_link },
137 	{ "I2C7", 1, i2c7_link },
138 	{ "I2C8", 1, i2c8_link },
139 	{ "I2C9", 2, i2c9_link },
140 	{ "I2C10", 2, i2c10_link },
141 	{ "I2C11", 2, i2c11_link },
142 	{ "I2C12", 2, i2c12_link },
143 	{ "I2C13", 2, i2c13_link },
144 	{ "I2C14", 1, i2c14_link },
145 	{ "SD2", 1, sdio2_link },
146 	{ "SD1", 1, sdio1_link },
147 	{ "SPI1", 1, spi1_link},
148 	{ "SPI1CS1", 1, spi1cs1_link},
149 };
150 
151 static int ast2400_pinctrl_get_groups_count(struct udevice *dev)
152 {
153 	debug("PINCTRL: get_(functions/groups)_count\n");
154 
155 	return ARRAY_SIZE(ast2400_groups);
156 }
157 
158 static const char *ast2400_pinctrl_get_group_name(struct udevice *dev,
159 						  unsigned selector)
160 {
161 	debug("PINCTRL: get_(function/group)_name %u\n", selector);
162 
163 	return ast2400_groups[selector].group_name;
164 }
165 
166 static int ast2400_pinctrl_group_set(struct udevice *dev, unsigned selector,
167 				     unsigned func_selector)
168 {
169 	struct ast2400_pinctrl_priv *priv = dev_get_priv(dev);
170 	const struct aspeed_group_config *config;
171 	const struct aspeed_sig_desc *descs;
172 	u32 *ctrl_reg = (u32*)priv->scu;
173 	int i;
174 
175 	debug("PINCTRL: group_set <%u, %u> \n", selector, func_selector);
176 	if (selector >= ARRAY_SIZE(ast2400_groups))
177 		return -EINVAL;
178 
179 	config = &ast2400_groups[selector];
180 
181 	for( i = 0; i < config->ndescs; i++) {
182 		descs = &config->descs[i];
183 		if(descs->clr) {
184 			clrbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
185 		} else {
186 			setbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
187 		}
188 	}
189 
190 	return 0;
191 }
192 
193 static struct pinctrl_ops ast2400_pinctrl_ops = {
194 	.set_state = pinctrl_generic_set_state,
195 	.get_groups_count = ast2400_pinctrl_get_groups_count,
196 	.get_group_name = ast2400_pinctrl_get_group_name,
197 	.get_functions_count = ast2400_pinctrl_get_groups_count,
198 	.get_function_name = ast2400_pinctrl_get_group_name,
199 	.pinmux_group_set = ast2400_pinctrl_group_set,
200 };
201 
202 static const struct udevice_id ast2400_pinctrl_ids[] = {
203 	{ .compatible = "aspeed,g4-pinctrl" },
204 	{ }
205 };
206 
207 U_BOOT_DRIVER(pinctrl_aspeed) = {
208 	.name = "aspeed_ast2400_pinctrl",
209 	.id = UCLASS_PINCTRL,
210 	.of_match = ast2400_pinctrl_ids,
211 	.priv_auto_alloc_size = sizeof(struct ast2400_pinctrl_priv),
212 	.ops = &ast2400_pinctrl_ops,
213 	.probe = ast2400_pinctrl_probe,
214 };
215