xref: /openbmc/u-boot/drivers/pinctrl/aspeed/pinctrl_ast2500.c (revision 831c69aaeca342c36c5f11985395032e0a538877)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
24f0e44e4Smaxims@google.com /*
34f0e44e4Smaxims@google.com  * Copyright 2017 Google, Inc
44f0e44e4Smaxims@google.com  */
54f0e44e4Smaxims@google.com 
64f0e44e4Smaxims@google.com #include <common.h>
74f0e44e4Smaxims@google.com #include <dm.h>
84f0e44e4Smaxims@google.com #include <errno.h>
94f0e44e4Smaxims@google.com #include <asm/io.h>
104f0e44e4Smaxims@google.com #include <asm/arch/pinctrl.h>
114f0e44e4Smaxims@google.com #include <asm/arch/scu_ast2500.h>
124f0e44e4Smaxims@google.com #include <dm/pinctrl.h>
13f13f9036Sryan_chen #include "pinctrl-aspeed.h"
144f0e44e4Smaxims@google.com /*
154f0e44e4Smaxims@google.com  * This driver works with very simple configuration that has the same name
164f0e44e4Smaxims@google.com  * for group and function. This way it is compatible with the Linux Kernel
174f0e44e4Smaxims@google.com  * driver.
184f0e44e4Smaxims@google.com  */
194f0e44e4Smaxims@google.com 
204f0e44e4Smaxims@google.com struct ast2500_pinctrl_priv {
214f0e44e4Smaxims@google.com 	struct ast2500_scu *scu;
224f0e44e4Smaxims@google.com };
234f0e44e4Smaxims@google.com 
ast2500_pinctrl_probe(struct udevice * dev)244f0e44e4Smaxims@google.com static int ast2500_pinctrl_probe(struct udevice *dev)
254f0e44e4Smaxims@google.com {
264f0e44e4Smaxims@google.com 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
2781cf3e0dSryan_chen 	struct udevice *clk_dev;
2881cf3e0dSryan_chen 	int ret = 0;
294f0e44e4Smaxims@google.com 
3081cf3e0dSryan_chen 	/* find SCU base address from clock device */
3181cf3e0dSryan_chen 	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(aspeed_scu),
3281cf3e0dSryan_chen                                           &clk_dev);
3381cf3e0dSryan_chen         if (ret) {
34f9aa0ee1Sryan_chen 		debug("clock device not found\n");
3581cf3e0dSryan_chen 		return ret;
3681cf3e0dSryan_chen         }
3781cf3e0dSryan_chen 
3881cf3e0dSryan_chen 	priv->scu = devfdt_get_addr_ptr(clk_dev);
3981cf3e0dSryan_chen 	if (IS_ERR(priv->scu)) {
40f9aa0ee1Sryan_chen 		debug("%s(): can't get SCU\n", __func__);
4181cf3e0dSryan_chen 		return PTR_ERR(priv->scu);
4281cf3e0dSryan_chen 	}
434f0e44e4Smaxims@google.com 
444f0e44e4Smaxims@google.com 	return 0;
454f0e44e4Smaxims@google.com }
464f0e44e4Smaxims@google.com 
47f13f9036Sryan_chen static struct aspeed_sig_desc mac1_link[] = {
48f13f9036Sryan_chen 	{ 0x80, BIT(0), 0	},
494f0e44e4Smaxims@google.com };
504f0e44e4Smaxims@google.com 
51f13f9036Sryan_chen static struct aspeed_sig_desc mac2_link[] = {
52f13f9036Sryan_chen 	{ 0x80, BIT(1), 0	},
53f13f9036Sryan_chen };
54f13f9036Sryan_chen 
55f13f9036Sryan_chen static struct aspeed_sig_desc mdio1_link[] = {
56f13f9036Sryan_chen 	{ 0x88, BIT(31) | BIT(30), 0	},
57f13f9036Sryan_chen };
58f13f9036Sryan_chen 
59f13f9036Sryan_chen static struct aspeed_sig_desc mdio2_link[] = {
60f13f9036Sryan_chen 	{ 0x90, BIT(2), 0	},
61f13f9036Sryan_chen };
62f13f9036Sryan_chen 
63f13f9036Sryan_chen static struct aspeed_sig_desc i2c3_link[] = {
64f13f9036Sryan_chen 	{ 0x90, BIT(16), 0	},
65f13f9036Sryan_chen };
66f13f9036Sryan_chen 
67f13f9036Sryan_chen static struct aspeed_sig_desc i2c4_link[] = {
68f13f9036Sryan_chen 	{ 0x90, BIT(17), 0	},
69f13f9036Sryan_chen };
70f13f9036Sryan_chen 
71f13f9036Sryan_chen static struct aspeed_sig_desc i2c5_link[] = {
72f13f9036Sryan_chen 	{ 0x90, BIT(18), 0	},
73f13f9036Sryan_chen };
74f13f9036Sryan_chen 
75f13f9036Sryan_chen static struct aspeed_sig_desc i2c6_link[] = {
76f13f9036Sryan_chen 	{ 0x90, BIT(19), 0	},
77f13f9036Sryan_chen };
78f13f9036Sryan_chen 
79f13f9036Sryan_chen static struct aspeed_sig_desc i2c7_link[] = {
80f13f9036Sryan_chen 	{ 0x90, BIT(20), 0	},
81f13f9036Sryan_chen };
82f13f9036Sryan_chen 
83f13f9036Sryan_chen static struct aspeed_sig_desc i2c8_link[] = {
84f13f9036Sryan_chen 	{ 0x90, BIT(21), 0	},
85f13f9036Sryan_chen };
86f13f9036Sryan_chen 
87f13f9036Sryan_chen static struct aspeed_sig_desc i2c9_link[] = {
88f13f9036Sryan_chen 	{ 0x90, BIT(22), 0	},
89f13f9036Sryan_chen 	{ 0x90, BIT(6), 1	},
90f13f9036Sryan_chen };
91f13f9036Sryan_chen 
92f13f9036Sryan_chen static struct aspeed_sig_desc i2c10_link[] = {
93f13f9036Sryan_chen 	{ 0x90, BIT(23), 0	},
94f13f9036Sryan_chen 	{ 0x90, BIT(0), 1	},
95f13f9036Sryan_chen };
96f13f9036Sryan_chen 
97f13f9036Sryan_chen static struct aspeed_sig_desc i2c11_link[] = {
98f13f9036Sryan_chen 	{ 0x90, BIT(24), 0	},
99f13f9036Sryan_chen 	{ 0x90, BIT(0), 1	},
100f13f9036Sryan_chen };
101f13f9036Sryan_chen 
102f13f9036Sryan_chen static struct aspeed_sig_desc i2c12_link[] = {
103f13f9036Sryan_chen 	{ 0x90, BIT(25), 0	},
104f13f9036Sryan_chen 	{ 0x90, BIT(0), 1	},
105f13f9036Sryan_chen };
106f13f9036Sryan_chen 
107f13f9036Sryan_chen static struct aspeed_sig_desc i2c13_link[] = {
108f13f9036Sryan_chen 	{ 0x90, BIT(26), 0	},
109f13f9036Sryan_chen 	{ 0x90, BIT(0), 1	},
110f13f9036Sryan_chen };
111f13f9036Sryan_chen 
112f13f9036Sryan_chen static struct aspeed_sig_desc i2c14_link[] = {
113f13f9036Sryan_chen 	{ 0x90, BIT(27), 0	},
114f13f9036Sryan_chen };
115f13f9036Sryan_chen 
116f13f9036Sryan_chen static struct aspeed_sig_desc sdio1_link[] = {
117f13f9036Sryan_chen 	{ 0x90, BIT(0), 0	},
118f13f9036Sryan_chen };
119f13f9036Sryan_chen 
120f13f9036Sryan_chen static struct aspeed_sig_desc sdio2_link[] = {
121f13f9036Sryan_chen 	{ 0x90, BIT(1), 0	},
122f13f9036Sryan_chen };
123f13f9036Sryan_chen 
124ce89c374SChin-Ting Kuo static struct aspeed_sig_desc spi1cs1_link[] = {
125ce89c374SChin-Ting Kuo 	{ 0x80, BIT(15), 0},
126ce89c374SChin-Ting Kuo };
127ce89c374SChin-Ting Kuo 
128ce89c374SChin-Ting Kuo static struct aspeed_sig_desc spi1_link[] = {
129ce89c374SChin-Ting Kuo 	{ 0x70, BIT(12), 0},
130ce89c374SChin-Ting Kuo };
131ce89c374SChin-Ting Kuo 
132*831c69aaSneal_liu static struct aspeed_sig_desc usb2ah_link[] = {
133*831c69aaSneal_liu 	{ 0x90, BIT(29), 0},
134*831c69aaSneal_liu };
135*831c69aaSneal_liu 
136*831c69aaSneal_liu static struct aspeed_sig_desc usb2bh_link[] = {
137*831c69aaSneal_liu 	{ 0x94, BIT(14), 0},
138*831c69aaSneal_liu 	{ 0x94, BIT(13), 1},
139*831c69aaSneal_liu };
140*831c69aaSneal_liu 
141f13f9036Sryan_chen static const struct aspeed_group_config ast2500_groups[] = {
142f13f9036Sryan_chen 	{ "MAC1LINK", 1, mac1_link },
143f13f9036Sryan_chen 	{ "MAC2LINK", 1, mac2_link },
144f13f9036Sryan_chen 	{ "MDIO1", 1, mdio1_link },
145f13f9036Sryan_chen 	{ "MDIO2", 1, mdio2_link },
146f13f9036Sryan_chen 	{ "I2C3", 1, i2c3_link },
147f13f9036Sryan_chen 	{ "I2C4", 1, i2c4_link },
148f13f9036Sryan_chen 	{ "I2C5", 1, i2c5_link },
149f13f9036Sryan_chen 	{ "I2C6", 1, i2c6_link },
150f13f9036Sryan_chen 	{ "I2C7", 1, i2c7_link },
151f13f9036Sryan_chen 	{ "I2C8", 1, i2c8_link },
152f13f9036Sryan_chen 	{ "I2C9", 2, i2c9_link },
153f13f9036Sryan_chen 	{ "I2C10", 2, i2c10_link },
154f13f9036Sryan_chen 	{ "I2C11", 2, i2c11_link },
155f13f9036Sryan_chen 	{ "I2C12", 2, i2c12_link },
156f13f9036Sryan_chen 	{ "I2C13", 2, i2c13_link },
157f13f9036Sryan_chen 	{ "I2C14", 1, i2c14_link },
158a245d114Sryan_chen 	{ "SD2", 1, sdio2_link },
159a245d114Sryan_chen 	{ "SD1", 1, sdio1_link },
160ce89c374SChin-Ting Kuo 	{ "SPI1", 1, spi1_link},
161ce89c374SChin-Ting Kuo 	{ "SPI1CS1", 1, spi1cs1_link},
162*831c69aaSneal_liu 	{ "USB2AH", 1, usb2ah_link },
163*831c69aaSneal_liu 	{ "USB2BH", 2, usb2bh_link },
1644f0e44e4Smaxims@google.com };
1654f0e44e4Smaxims@google.com 
ast2500_pinctrl_get_groups_count(struct udevice * dev)1664f0e44e4Smaxims@google.com static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
1674f0e44e4Smaxims@google.com {
1684f0e44e4Smaxims@google.com 	debug("PINCTRL: get_(functions/groups)_count\n");
1694f0e44e4Smaxims@google.com 
1704f0e44e4Smaxims@google.com 	return ARRAY_SIZE(ast2500_groups);
1714f0e44e4Smaxims@google.com }
1724f0e44e4Smaxims@google.com 
ast2500_pinctrl_get_group_name(struct udevice * dev,unsigned selector)1734f0e44e4Smaxims@google.com static const char *ast2500_pinctrl_get_group_name(struct udevice *dev,
1744f0e44e4Smaxims@google.com 						  unsigned selector)
1754f0e44e4Smaxims@google.com {
1764f0e44e4Smaxims@google.com 	debug("PINCTRL: get_(function/group)_name %u\n", selector);
1774f0e44e4Smaxims@google.com 
1784f0e44e4Smaxims@google.com 	return ast2500_groups[selector].group_name;
1794f0e44e4Smaxims@google.com }
1804f0e44e4Smaxims@google.com 
ast2500_pinctrl_group_set(struct udevice * dev,unsigned selector,unsigned func_selector)1814f0e44e4Smaxims@google.com static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector,
1824f0e44e4Smaxims@google.com 				     unsigned func_selector)
1834f0e44e4Smaxims@google.com {
1844f0e44e4Smaxims@google.com 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
185f13f9036Sryan_chen 	const struct aspeed_group_config *config;
186f13f9036Sryan_chen 	const struct aspeed_sig_desc *descs;
187f13f9036Sryan_chen 	u32 *ctrl_reg = (u32*)priv->scu;
188f13f9036Sryan_chen 	int i;
1894f0e44e4Smaxims@google.com 
1904f0e44e4Smaxims@google.com 	debug("PINCTRL: group_set <%u, %u> \n", selector, func_selector);
1914f0e44e4Smaxims@google.com 	if (selector >= ARRAY_SIZE(ast2500_groups))
1924f0e44e4Smaxims@google.com 		return -EINVAL;
1934f0e44e4Smaxims@google.com 
1944f0e44e4Smaxims@google.com 	config = &ast2500_groups[selector];
1954f0e44e4Smaxims@google.com 
196f13f9036Sryan_chen 	for( i = 0; i < config->ndescs; i++) {
197f13f9036Sryan_chen 		descs = &config->descs[i];
198f13f9036Sryan_chen 		if(descs->clr) {
199f13f9036Sryan_chen 			clrbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
200f13f9036Sryan_chen 		} else {
201f13f9036Sryan_chen 			setbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set);
202f13f9036Sryan_chen 		}
203f13f9036Sryan_chen 	}
204a245d114Sryan_chen 
2054f0e44e4Smaxims@google.com 	return 0;
2064f0e44e4Smaxims@google.com }
2074f0e44e4Smaxims@google.com 
2084f0e44e4Smaxims@google.com static struct pinctrl_ops ast2500_pinctrl_ops = {
2094f0e44e4Smaxims@google.com 	.set_state = pinctrl_generic_set_state,
2104f0e44e4Smaxims@google.com 	.get_groups_count = ast2500_pinctrl_get_groups_count,
2114f0e44e4Smaxims@google.com 	.get_group_name = ast2500_pinctrl_get_group_name,
2124f0e44e4Smaxims@google.com 	.get_functions_count = ast2500_pinctrl_get_groups_count,
2134f0e44e4Smaxims@google.com 	.get_function_name = ast2500_pinctrl_get_group_name,
2144f0e44e4Smaxims@google.com 	.pinmux_group_set = ast2500_pinctrl_group_set,
2154f0e44e4Smaxims@google.com };
2164f0e44e4Smaxims@google.com 
2174f0e44e4Smaxims@google.com static const struct udevice_id ast2500_pinctrl_ids[] = {
2184f0e44e4Smaxims@google.com 	{ .compatible = "aspeed,g5-pinctrl" },
2194f0e44e4Smaxims@google.com 	{ }
2204f0e44e4Smaxims@google.com };
2214f0e44e4Smaxims@google.com 
222f13f9036Sryan_chen U_BOOT_DRIVER(pinctrl_aspeed) = {
2234f0e44e4Smaxims@google.com 	.name = "aspeed_ast2500_pinctrl",
2244f0e44e4Smaxims@google.com 	.id = UCLASS_PINCTRL,
2254f0e44e4Smaxims@google.com 	.of_match = ast2500_pinctrl_ids,
2264f0e44e4Smaxims@google.com 	.priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv),
2274f0e44e4Smaxims@google.com 	.ops = &ast2500_pinctrl_ops,
2284f0e44e4Smaxims@google.com 	.probe = ast2500_pinctrl_probe,
2294f0e44e4Smaxims@google.com };
230