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