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