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