0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/platform_device.h>
0011 #include <linux/module.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_net.h>
0016 #include <linux/phy.h>
0017 #include <linux/phy/phy.h>
0018 #include <linux/regmap.h>
0019
0020
0021 #define AM33XX_GMII_SEL_MODE_MII 0
0022 #define AM33XX_GMII_SEL_MODE_RMII 1
0023 #define AM33XX_GMII_SEL_MODE_RGMII 2
0024
0025 enum {
0026 PHY_GMII_SEL_PORT_MODE = 0,
0027 PHY_GMII_SEL_RGMII_ID_MODE,
0028 PHY_GMII_SEL_RMII_IO_CLK_EN,
0029 PHY_GMII_SEL_LAST,
0030 };
0031
0032 struct phy_gmii_sel_phy_priv {
0033 struct phy_gmii_sel_priv *priv;
0034 u32 id;
0035 struct phy *if_phy;
0036 int rmii_clock_external;
0037 int phy_if_mode;
0038 struct regmap_field *fields[PHY_GMII_SEL_LAST];
0039 };
0040
0041 struct phy_gmii_sel_soc_data {
0042 u32 num_ports;
0043 u32 features;
0044 const struct reg_field (*regfields)[PHY_GMII_SEL_LAST];
0045 bool use_of_data;
0046 };
0047
0048 struct phy_gmii_sel_priv {
0049 struct device *dev;
0050 const struct phy_gmii_sel_soc_data *soc_data;
0051 struct regmap *regmap;
0052 struct phy_provider *phy_provider;
0053 struct phy_gmii_sel_phy_priv *if_phys;
0054 u32 num_ports;
0055 u32 reg_offset;
0056 };
0057
0058 static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
0059 {
0060 struct phy_gmii_sel_phy_priv *if_phy = phy_get_drvdata(phy);
0061 const struct phy_gmii_sel_soc_data *soc_data = if_phy->priv->soc_data;
0062 struct device *dev = if_phy->priv->dev;
0063 struct regmap_field *regfield;
0064 int ret, rgmii_id = 0;
0065 u32 gmii_sel_mode = 0;
0066
0067 if (mode != PHY_MODE_ETHERNET)
0068 return -EINVAL;
0069
0070 switch (submode) {
0071 case PHY_INTERFACE_MODE_RMII:
0072 gmii_sel_mode = AM33XX_GMII_SEL_MODE_RMII;
0073 break;
0074
0075 case PHY_INTERFACE_MODE_RGMII:
0076 case PHY_INTERFACE_MODE_RGMII_RXID:
0077 gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII;
0078 break;
0079
0080 case PHY_INTERFACE_MODE_RGMII_ID:
0081 case PHY_INTERFACE_MODE_RGMII_TXID:
0082 gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII;
0083 rgmii_id = 1;
0084 break;
0085
0086 case PHY_INTERFACE_MODE_MII:
0087 case PHY_INTERFACE_MODE_GMII:
0088 gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII;
0089 break;
0090
0091 default:
0092 dev_warn(dev, "port%u: unsupported mode: \"%s\"\n",
0093 if_phy->id, phy_modes(submode));
0094 return -EINVAL;
0095 }
0096
0097 if_phy->phy_if_mode = submode;
0098
0099 dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
0100 __func__, if_phy->id, submode, rgmii_id,
0101 if_phy->rmii_clock_external);
0102
0103 regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE];
0104 ret = regmap_field_write(regfield, gmii_sel_mode);
0105 if (ret) {
0106 dev_err(dev, "port%u: set mode fail %d", if_phy->id, ret);
0107 return ret;
0108 }
0109
0110 if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE) &&
0111 if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE]) {
0112 regfield = if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE];
0113 ret = regmap_field_write(regfield, rgmii_id);
0114 if (ret)
0115 return ret;
0116 }
0117
0118 if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) &&
0119 if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN]) {
0120 regfield = if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN];
0121 ret = regmap_field_write(regfield,
0122 if_phy->rmii_clock_external);
0123 }
0124
0125 return 0;
0126 }
0127
0128 static const
0129 struct reg_field phy_gmii_sel_fields_am33xx[][PHY_GMII_SEL_LAST] = {
0130 {
0131 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x650, 0, 1),
0132 [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x650, 4, 4),
0133 [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD(0x650, 6, 6),
0134 },
0135 {
0136 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x650, 2, 3),
0137 [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD(0x650, 5, 5),
0138 [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD(0x650, 7, 7),
0139 },
0140 };
0141
0142 static const
0143 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am33xx = {
0144 .num_ports = 2,
0145 .features = BIT(PHY_GMII_SEL_RGMII_ID_MODE) |
0146 BIT(PHY_GMII_SEL_RMII_IO_CLK_EN),
0147 .regfields = phy_gmii_sel_fields_am33xx,
0148 };
0149
0150 static const
0151 struct reg_field phy_gmii_sel_fields_dra7[][PHY_GMII_SEL_LAST] = {
0152 {
0153 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 0, 1),
0154 },
0155 {
0156 [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 4, 5),
0157 },
0158 };
0159
0160 static const
0161 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dra7 = {
0162 .num_ports = 2,
0163 .regfields = phy_gmii_sel_fields_dra7,
0164 };
0165
0166 static const
0167 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
0168 .num_ports = 2,
0169 .features = BIT(PHY_GMII_SEL_RGMII_ID_MODE),
0170 .regfields = phy_gmii_sel_fields_am33xx,
0171 };
0172
0173 static const
0174 struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
0175 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
0176 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
0177 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
0178 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
0179 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
0180 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
0181 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
0182 { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
0183 };
0184
0185 static const
0186 struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
0187 .use_of_data = true,
0188 .regfields = phy_gmii_sel_fields_am654,
0189 };
0190
0191 static const struct of_device_id phy_gmii_sel_id_table[] = {
0192 {
0193 .compatible = "ti,am3352-phy-gmii-sel",
0194 .data = &phy_gmii_sel_soc_am33xx,
0195 },
0196 {
0197 .compatible = "ti,dra7xx-phy-gmii-sel",
0198 .data = &phy_gmii_sel_soc_dra7,
0199 },
0200 {
0201 .compatible = "ti,am43xx-phy-gmii-sel",
0202 .data = &phy_gmii_sel_soc_am33xx,
0203 },
0204 {
0205 .compatible = "ti,dm814-phy-gmii-sel",
0206 .data = &phy_gmii_sel_soc_dm814,
0207 },
0208 {
0209 .compatible = "ti,am654-phy-gmii-sel",
0210 .data = &phy_gmii_sel_soc_am654,
0211 },
0212 {}
0213 };
0214 MODULE_DEVICE_TABLE(of, phy_gmii_sel_id_table);
0215
0216 static const struct phy_ops phy_gmii_sel_ops = {
0217 .set_mode = phy_gmii_sel_mode,
0218 .owner = THIS_MODULE,
0219 };
0220
0221 static struct phy *phy_gmii_sel_of_xlate(struct device *dev,
0222 struct of_phandle_args *args)
0223 {
0224 struct phy_gmii_sel_priv *priv = dev_get_drvdata(dev);
0225 int phy_id = args->args[0];
0226
0227 if (args->args_count < 1)
0228 return ERR_PTR(-EINVAL);
0229 if (!priv || !priv->if_phys)
0230 return ERR_PTR(-ENODEV);
0231 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) &&
0232 args->args_count < 2)
0233 return ERR_PTR(-EINVAL);
0234 if (phy_id > priv->num_ports)
0235 return ERR_PTR(-EINVAL);
0236 if (phy_id != priv->if_phys[phy_id - 1].id)
0237 return ERR_PTR(-EINVAL);
0238
0239 phy_id--;
0240 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN))
0241 priv->if_phys[phy_id].rmii_clock_external = args->args[1];
0242 dev_dbg(dev, "%s id:%u ext:%d\n", __func__,
0243 priv->if_phys[phy_id].id, args->args[1]);
0244
0245 return priv->if_phys[phy_id].if_phy;
0246 }
0247
0248 static int phy_gmii_init_phy(struct phy_gmii_sel_priv *priv, int port,
0249 struct phy_gmii_sel_phy_priv *if_phy)
0250 {
0251 const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data;
0252 struct device *dev = priv->dev;
0253 const struct reg_field *fields;
0254 struct regmap_field *regfield;
0255 struct reg_field field;
0256 int ret;
0257
0258 if_phy->id = port;
0259 if_phy->priv = priv;
0260
0261 fields = soc_data->regfields[port - 1];
0262 field = *fields++;
0263 field.reg += priv->reg_offset;
0264 dev_dbg(dev, "%s field %x %d %d\n", __func__,
0265 field.reg, field.msb, field.lsb);
0266
0267 regfield = devm_regmap_field_alloc(dev, priv->regmap, field);
0268 if (IS_ERR(regfield))
0269 return PTR_ERR(regfield);
0270 if_phy->fields[PHY_GMII_SEL_PORT_MODE] = regfield;
0271
0272 field = *fields++;
0273 field.reg += priv->reg_offset;
0274 if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE)) {
0275 regfield = devm_regmap_field_alloc(dev,
0276 priv->regmap,
0277 field);
0278 if (IS_ERR(regfield))
0279 return PTR_ERR(regfield);
0280 if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE] = regfield;
0281 dev_dbg(dev, "%s field %x %d %d\n", __func__,
0282 field.reg, field.msb, field.lsb);
0283 }
0284
0285 field = *fields;
0286 field.reg += priv->reg_offset;
0287 if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN)) {
0288 regfield = devm_regmap_field_alloc(dev,
0289 priv->regmap,
0290 field);
0291 if (IS_ERR(regfield))
0292 return PTR_ERR(regfield);
0293 if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN] = regfield;
0294 dev_dbg(dev, "%s field %x %d %d\n", __func__,
0295 field.reg, field.msb, field.lsb);
0296 }
0297
0298 if_phy->if_phy = devm_phy_create(dev,
0299 priv->dev->of_node,
0300 &phy_gmii_sel_ops);
0301 if (IS_ERR(if_phy->if_phy)) {
0302 ret = PTR_ERR(if_phy->if_phy);
0303 dev_err(dev, "Failed to create phy%d %d\n", port, ret);
0304 return ret;
0305 }
0306 phy_set_drvdata(if_phy->if_phy, if_phy);
0307
0308 return 0;
0309 }
0310
0311 static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv)
0312 {
0313 const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data;
0314 struct phy_gmii_sel_phy_priv *if_phys;
0315 struct device *dev = priv->dev;
0316 int i, ret;
0317
0318 if (soc_data->use_of_data) {
0319 const __be32 *offset;
0320 u64 size;
0321
0322 offset = of_get_address(dev->of_node, 0, &size, NULL);
0323 if (!offset)
0324 return -EINVAL;
0325 priv->num_ports = size / sizeof(u32);
0326 if (!priv->num_ports)
0327 return -EINVAL;
0328 priv->reg_offset = __be32_to_cpu(*offset);
0329 }
0330
0331 if_phys = devm_kcalloc(dev, priv->num_ports,
0332 sizeof(*if_phys), GFP_KERNEL);
0333 if (!if_phys)
0334 return -ENOMEM;
0335 dev_dbg(dev, "%s %d\n", __func__, priv->num_ports);
0336
0337 for (i = 0; i < priv->num_ports; i++) {
0338 ret = phy_gmii_init_phy(priv, i + 1, &if_phys[i]);
0339 if (ret)
0340 return ret;
0341 }
0342
0343 priv->if_phys = if_phys;
0344 return 0;
0345 }
0346
0347 static int phy_gmii_sel_probe(struct platform_device *pdev)
0348 {
0349 struct device *dev = &pdev->dev;
0350 struct device_node *node = dev->of_node;
0351 const struct of_device_id *of_id;
0352 struct phy_gmii_sel_priv *priv;
0353 int ret;
0354
0355 of_id = of_match_node(phy_gmii_sel_id_table, pdev->dev.of_node);
0356 if (!of_id)
0357 return -EINVAL;
0358
0359 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0360 if (!priv)
0361 return -ENOMEM;
0362
0363 priv->dev = &pdev->dev;
0364 priv->soc_data = of_id->data;
0365 priv->num_ports = priv->soc_data->num_ports;
0366
0367 priv->regmap = syscon_node_to_regmap(node->parent);
0368 if (IS_ERR(priv->regmap)) {
0369 ret = PTR_ERR(priv->regmap);
0370 dev_err(dev, "Failed to get syscon %d\n", ret);
0371 return ret;
0372 }
0373
0374 ret = phy_gmii_sel_init_ports(priv);
0375 if (ret)
0376 return ret;
0377
0378 dev_set_drvdata(&pdev->dev, priv);
0379
0380 priv->phy_provider =
0381 devm_of_phy_provider_register(dev,
0382 phy_gmii_sel_of_xlate);
0383 if (IS_ERR(priv->phy_provider)) {
0384 ret = PTR_ERR(priv->phy_provider);
0385 dev_err(dev, "Failed to create phy provider %d\n", ret);
0386 return ret;
0387 }
0388
0389 return 0;
0390 }
0391
0392 static struct platform_driver phy_gmii_sel_driver = {
0393 .probe = phy_gmii_sel_probe,
0394 .driver = {
0395 .name = "phy-gmii-sel",
0396 .of_match_table = phy_gmii_sel_id_table,
0397 },
0398 };
0399 module_platform_driver(phy_gmii_sel_driver);
0400
0401 MODULE_LICENSE("GPL v2");
0402 MODULE_AUTHOR("Grygorii Strashko <grygorii.strashko@ti.com>");
0403 MODULE_DESCRIPTION("TI CPSW Port's PHY Interface Mode selection Driver");