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 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 128*094f6003SZev Weiss static struct aspeed_sig_desc txd3_link[] = { 129*094f6003SZev Weiss { 0x80, BIT(22), 0}, 130*094f6003SZev Weiss }; 131*094f6003SZev Weiss 132*094f6003SZev Weiss static struct aspeed_sig_desc rxd3_link[] = { 133*094f6003SZev Weiss { 0x80, BIT(23), 0}, 134*094f6003SZev Weiss }; 135*094f6003SZev Weiss 136b1be71f7Sryan_chen static const struct aspeed_group_config ast2400_groups[] = { 137b1be71f7Sryan_chen { "MAC1LINK", 1, mac1_link }, 138b1be71f7Sryan_chen { "MAC2LINK", 1, mac2_link }, 139b1be71f7Sryan_chen { "MDIO1", 1, mdio1_link }, 140b1be71f7Sryan_chen { "MDIO2", 1, mdio2_link }, 141b1be71f7Sryan_chen { "I2C3", 1, i2c3_link }, 142b1be71f7Sryan_chen { "I2C4", 1, i2c4_link }, 143b1be71f7Sryan_chen { "I2C5", 1, i2c5_link }, 144b1be71f7Sryan_chen { "I2C6", 1, i2c6_link }, 145b1be71f7Sryan_chen { "I2C7", 1, i2c7_link }, 146b1be71f7Sryan_chen { "I2C8", 1, i2c8_link }, 14753013019SRyan Chen { "I2C9", 1, i2c9_link }, 148b1be71f7Sryan_chen { "I2C10", 2, i2c10_link }, 149b1be71f7Sryan_chen { "I2C11", 2, i2c11_link }, 150b1be71f7Sryan_chen { "I2C12", 2, i2c12_link }, 151b1be71f7Sryan_chen { "I2C13", 2, i2c13_link }, 152b1be71f7Sryan_chen { "I2C14", 1, i2c14_link }, 153b1be71f7Sryan_chen { "SD2", 1, sdio2_link }, 154b1be71f7Sryan_chen { "SD1", 1, sdio1_link }, 155b1be71f7Sryan_chen { "SPI1", 1, spi1_link}, 156b1be71f7Sryan_chen { "SPI1CS1", 1, spi1cs1_link}, 157*094f6003SZev Weiss { "TXD3", 1, txd3_link }, 158*094f6003SZev Weiss { "RXD3", 1, rxd3_link }, 159b1be71f7Sryan_chen }; 160b1be71f7Sryan_chen 161b1be71f7Sryan_chen static int ast2400_pinctrl_get_groups_count(struct udevice *dev) 162b1be71f7Sryan_chen { 163b1be71f7Sryan_chen debug("PINCTRL: get_(functions/groups)_count\n"); 164b1be71f7Sryan_chen 165b1be71f7Sryan_chen return ARRAY_SIZE(ast2400_groups); 166b1be71f7Sryan_chen } 167b1be71f7Sryan_chen 168b1be71f7Sryan_chen static const char *ast2400_pinctrl_get_group_name(struct udevice *dev, 169b1be71f7Sryan_chen unsigned selector) 170b1be71f7Sryan_chen { 171b1be71f7Sryan_chen debug("PINCTRL: get_(function/group)_name %u\n", selector); 172b1be71f7Sryan_chen 173b1be71f7Sryan_chen return ast2400_groups[selector].group_name; 174b1be71f7Sryan_chen } 175b1be71f7Sryan_chen 176b1be71f7Sryan_chen static int ast2400_pinctrl_group_set(struct udevice *dev, unsigned selector, 177b1be71f7Sryan_chen unsigned func_selector) 178b1be71f7Sryan_chen { 179b1be71f7Sryan_chen struct ast2400_pinctrl_priv *priv = dev_get_priv(dev); 180b1be71f7Sryan_chen const struct aspeed_group_config *config; 181b1be71f7Sryan_chen const struct aspeed_sig_desc *descs; 182b1be71f7Sryan_chen u32 *ctrl_reg = (u32*)priv->scu; 183b1be71f7Sryan_chen int i; 184b1be71f7Sryan_chen 185b1be71f7Sryan_chen debug("PINCTRL: group_set <%u, %u> \n", selector, func_selector); 186b1be71f7Sryan_chen if (selector >= ARRAY_SIZE(ast2400_groups)) 187b1be71f7Sryan_chen return -EINVAL; 188b1be71f7Sryan_chen 189b1be71f7Sryan_chen config = &ast2400_groups[selector]; 190b1be71f7Sryan_chen 191b1be71f7Sryan_chen for( i = 0; i < config->ndescs; i++) { 192b1be71f7Sryan_chen descs = &config->descs[i]; 193b1be71f7Sryan_chen if(descs->clr) { 194b1be71f7Sryan_chen clrbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set); 195b1be71f7Sryan_chen } else { 196b1be71f7Sryan_chen setbits_le32((u32)ctrl_reg + descs->offset, descs->reg_set); 197b1be71f7Sryan_chen } 198b1be71f7Sryan_chen } 199b1be71f7Sryan_chen 200b1be71f7Sryan_chen return 0; 201b1be71f7Sryan_chen } 202b1be71f7Sryan_chen 203b1be71f7Sryan_chen static struct pinctrl_ops ast2400_pinctrl_ops = { 204b1be71f7Sryan_chen .set_state = pinctrl_generic_set_state, 205b1be71f7Sryan_chen .get_groups_count = ast2400_pinctrl_get_groups_count, 206b1be71f7Sryan_chen .get_group_name = ast2400_pinctrl_get_group_name, 207b1be71f7Sryan_chen .get_functions_count = ast2400_pinctrl_get_groups_count, 208b1be71f7Sryan_chen .get_function_name = ast2400_pinctrl_get_group_name, 209b1be71f7Sryan_chen .pinmux_group_set = ast2400_pinctrl_group_set, 210b1be71f7Sryan_chen }; 211b1be71f7Sryan_chen 212b1be71f7Sryan_chen static const struct udevice_id ast2400_pinctrl_ids[] = { 213b1be71f7Sryan_chen { .compatible = "aspeed,g4-pinctrl" }, 214b1be71f7Sryan_chen { } 215b1be71f7Sryan_chen }; 216b1be71f7Sryan_chen 217b1be71f7Sryan_chen U_BOOT_DRIVER(pinctrl_aspeed) = { 218b1be71f7Sryan_chen .name = "aspeed_ast2400_pinctrl", 219b1be71f7Sryan_chen .id = UCLASS_PINCTRL, 220b1be71f7Sryan_chen .of_match = ast2400_pinctrl_ids, 221b1be71f7Sryan_chen .priv_auto_alloc_size = sizeof(struct ast2400_pinctrl_priv), 222b1be71f7Sryan_chen .ops = &ast2400_pinctrl_ops, 223b1be71f7Sryan_chen .probe = ast2400_pinctrl_probe, 224b1be71f7Sryan_chen }; 225