1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <asm/io.h>
10 #include <asm/arch/pinctrl.h>
11 #include <asm/arch/scu_ast2500.h>
12 #include <dm/pinctrl.h>
13 #include "pinctrl-aspeed.h"
14 /*
15  * This driver works with very simple configuration that has the same name
16  * for group and function. This way it is compatible with the Linux Kernel
17  * driver.
18  */
19 
20 struct ast2500_pinctrl_priv {
21 	struct ast2500_scu *scu;
22 };
23 
24 static int ast2500_pinctrl_probe(struct udevice *dev)
25 {
26 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
27 
28 	priv->scu = ast_get_scu();
29 
30 	return 0;
31 }
32 
33 static struct aspeed_sig_desc mac1_link[] = {
34 	{ 0x80, BIT(0), 0	},
35 };
36 
37 static struct aspeed_sig_desc mac2_link[] = {
38 	{ 0x80, BIT(1), 0	},
39 };
40 
41 static struct aspeed_sig_desc mdio1_link[] = {
42 	{ 0x88, BIT(31) | BIT(30), 0	},
43 };
44 
45 static struct aspeed_sig_desc mdio2_link[] = {
46 	{ 0x90, BIT(2), 0	},
47 };
48 
49 static struct aspeed_sig_desc i2c3_link[] = {
50 	{ 0x90, BIT(16), 0	},
51 };
52 
53 static struct aspeed_sig_desc i2c4_link[] = {
54 	{ 0x90, BIT(17), 0	},
55 };
56 
57 static struct aspeed_sig_desc i2c5_link[] = {
58 	{ 0x90, BIT(18), 0	},
59 };
60 
61 static struct aspeed_sig_desc i2c6_link[] = {
62 	{ 0x90, BIT(19), 0	},
63 };
64 
65 static struct aspeed_sig_desc i2c7_link[] = {
66 	{ 0x90, BIT(20), 0	},
67 };
68 
69 static struct aspeed_sig_desc i2c8_link[] = {
70 	{ 0x90, BIT(21), 0	},
71 };
72 
73 static struct aspeed_sig_desc i2c9_link[] = {
74 	{ 0x90, BIT(22), 0	},
75 	{ 0x90, BIT(6), 1	},
76 };
77 
78 static struct aspeed_sig_desc i2c10_link[] = {
79 	{ 0x90, BIT(23), 0	},
80 	{ 0x90, BIT(0), 1	},
81 };
82 
83 static struct aspeed_sig_desc i2c11_link[] = {
84 	{ 0x90, BIT(24), 0	},
85 	{ 0x90, BIT(0), 1	},
86 };
87 
88 static struct aspeed_sig_desc i2c12_link[] = {
89 	{ 0x90, BIT(25), 0	},
90 	{ 0x90, BIT(0), 1	},
91 };
92 
93 static struct aspeed_sig_desc i2c13_link[] = {
94 	{ 0x90, BIT(26), 0	},
95 	{ 0x90, BIT(0), 1	},
96 };
97 
98 static struct aspeed_sig_desc i2c14_link[] = {
99 	{ 0x90, BIT(27), 0	},
100 };
101 
102 static struct aspeed_sig_desc sdio1_link[] = {
103 	{ 0x90, BIT(0), 0	},
104 };
105 
106 static struct aspeed_sig_desc sdio2_link[] = {
107 	{ 0x90, BIT(1), 0	},
108 };
109 
110 static const struct aspeed_group_config ast2500_groups[] = {
111 	{ "MAC1LINK", 1, mac1_link },
112 	{ "MAC2LINK", 1, mac2_link },
113 	{ "MDIO1", 1, mdio1_link },
114 	{ "MDIO2", 1, mdio2_link },
115 	{ "I2C3", 1, i2c3_link },
116 	{ "I2C4", 1, i2c4_link },
117 	{ "I2C5", 1, i2c5_link },
118 	{ "I2C6", 1, i2c6_link },
119 	{ "I2C7", 1, i2c7_link },
120 	{ "I2C8", 1, i2c8_link },
121 	{ "I2C9", 2, i2c9_link },
122 	{ "I2C10", 2, i2c10_link },
123 	{ "I2C11", 2, i2c11_link },
124 	{ "I2C12", 2, i2c12_link },
125 	{ "I2C13", 2, i2c13_link },
126 	{ "I2C14", 1, i2c14_link },
127 	{ "SDIO1", 1, sdio2_link },
128 	{ "SDIO0", 1, sdio1_link },
129 };
130 
131 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
132 {
133 	debug("PINCTRL: get_(functions/groups)_count\n");
134 
135 	return ARRAY_SIZE(ast2500_groups);
136 }
137 
138 static const char *ast2500_pinctrl_get_group_name(struct udevice *dev,
139 						  unsigned selector)
140 {
141 	debug("PINCTRL: get_(function/group)_name %u\n", selector);
142 
143 	return ast2500_groups[selector].group_name;
144 }
145 
146 static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector,
147 				     unsigned func_selector)
148 {
149 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
150 	const struct aspeed_group_config *config;
151 	const struct aspeed_sig_desc *descs;
152 	u32 *ctrl_reg = (u32*)priv->scu;
153 	int i;
154 
155 	debug("PINCTRL: group_set <%u, %u>\n", selector, func_selector);
156 	if (selector >= ARRAY_SIZE(ast2500_groups))
157 		return -EINVAL;
158 
159 	config = &ast2500_groups[selector];
160 
161 	for( i = 0; i < config->ndescs; i++) {
162 		descs = &config->descs[i];
163 		if(descs->clr) {
164 			clrbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
165 		} else {
166 			setbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
167 		}
168 	}
169 	printf("done \n");
170 	return 0;
171 }
172 
173 static struct pinctrl_ops ast2500_pinctrl_ops = {
174 	.set_state = pinctrl_generic_set_state,
175 	.get_groups_count = ast2500_pinctrl_get_groups_count,
176 	.get_group_name = ast2500_pinctrl_get_group_name,
177 	.get_functions_count = ast2500_pinctrl_get_groups_count,
178 	.get_function_name = ast2500_pinctrl_get_group_name,
179 	.pinmux_group_set = ast2500_pinctrl_group_set,
180 };
181 
182 static const struct udevice_id ast2500_pinctrl_ids[] = {
183 	{ .compatible = "aspeed,g5-pinctrl" },
184 	{ }
185 };
186 
187 U_BOOT_DRIVER(pinctrl_aspeed) = {
188 	.name = "aspeed_ast2500_pinctrl",
189 	.id = UCLASS_PINCTRL,
190 	.of_match = ast2500_pinctrl_ids,
191 	.priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv),
192 	.ops = &ast2500_pinctrl_ops,
193 	.probe = ast2500_pinctrl_probe,
194 };
195