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