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