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