0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/slab.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/stmmac.h>
0014 #include <linux/phy.h>
0015 #include <linux/mfd/syscon.h>
0016 #include <linux/module.h>
0017 #include <linux/regmap.h>
0018 #include <linux/clk.h>
0019 #include <linux/of.h>
0020 #include <linux/of_device.h>
0021 #include <linux/of_net.h>
0022
0023 #include "stmmac_platform.h"
0024
0025 #define DWMAC_125MHZ 125000000
0026 #define DWMAC_50MHZ 50000000
0027 #define DWMAC_25MHZ 25000000
0028 #define DWMAC_2_5MHZ 2500000
0029
0030 #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
0031 iface == PHY_INTERFACE_MODE_RGMII_ID || \
0032 iface == PHY_INTERFACE_MODE_RGMII_RXID || \
0033 iface == PHY_INTERFACE_MODE_RGMII_TXID)
0034
0035 #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
0036 iface == PHY_INTERFACE_MODE_GMII)
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #define STIH4XX_RETIME_SRC_MASK GENMASK(8, 6)
0074 #define STIH4XX_ETH_SEL_TX_RETIME_CLK BIT(8)
0075 #define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
0076 #define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 #define STID127_RETIME_SRC_MASK GENMASK(7, 6)
0096 #define STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
0097 #define STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK BIT(6)
0098
0099 #define ENMII_MASK GENMASK(5, 5)
0100 #define ENMII BIT(5)
0101 #define EN_MASK GENMASK(1, 1)
0102 #define EN BIT(1)
0103
0104
0105
0106
0107
0108
0109
0110
0111 #define MII_PHY_SEL_MASK GENMASK(4, 2)
0112 #define ETH_PHY_SEL_RMII BIT(4)
0113 #define ETH_PHY_SEL_SGMII BIT(3)
0114 #define ETH_PHY_SEL_RGMII BIT(2)
0115 #define ETH_PHY_SEL_GMII 0x0
0116 #define ETH_PHY_SEL_MII 0x0
0117
0118 struct sti_dwmac {
0119 phy_interface_t interface;
0120 bool ext_phyclk;
0121 u32 tx_retime_src;
0122 struct clk *clk;
0123 u32 ctrl_reg;
0124 int clk_sel_reg;
0125 struct regmap *regmap;
0126 bool gmac_en;
0127 u32 speed;
0128 void (*fix_retime_src)(void *priv, unsigned int speed);
0129 };
0130
0131 struct sti_dwmac_of_data {
0132 void (*fix_retime_src)(void *priv, unsigned int speed);
0133 };
0134
0135 static u32 phy_intf_sels[] = {
0136 [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII,
0137 [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII,
0138 [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII,
0139 [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII,
0140 [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII,
0141 [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII,
0142 };
0143
0144 enum {
0145 TX_RETIME_SRC_NA = 0,
0146 TX_RETIME_SRC_TXCLK = 1,
0147 TX_RETIME_SRC_CLK_125,
0148 TX_RETIME_SRC_PHYCLK,
0149 TX_RETIME_SRC_CLKGEN,
0150 };
0151
0152 static u32 stih4xx_tx_retime_val[] = {
0153 [TX_RETIME_SRC_TXCLK] = STIH4XX_ETH_SEL_TXCLK_NOT_CLK125,
0154 [TX_RETIME_SRC_CLK_125] = 0x0,
0155 [TX_RETIME_SRC_PHYCLK] = STIH4XX_ETH_SEL_TX_RETIME_CLK,
0156 [TX_RETIME_SRC_CLKGEN] = STIH4XX_ETH_SEL_TX_RETIME_CLK
0157 | STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
0158 };
0159
0160 static void stih4xx_fix_retime_src(void *priv, u32 spd)
0161 {
0162 struct sti_dwmac *dwmac = priv;
0163 u32 src = dwmac->tx_retime_src;
0164 u32 reg = dwmac->ctrl_reg;
0165 u32 freq = 0;
0166
0167 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
0168 src = TX_RETIME_SRC_TXCLK;
0169 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
0170 if (dwmac->ext_phyclk) {
0171 src = TX_RETIME_SRC_PHYCLK;
0172 } else {
0173 src = TX_RETIME_SRC_CLKGEN;
0174 freq = DWMAC_50MHZ;
0175 }
0176 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
0177
0178 if (spd == SPEED_1000) {
0179 freq = DWMAC_125MHZ;
0180 } else {
0181
0182 src = TX_RETIME_SRC_CLKGEN;
0183 if (spd == SPEED_100)
0184 freq = DWMAC_25MHZ;
0185 else if (spd == SPEED_10)
0186 freq = DWMAC_2_5MHZ;
0187 }
0188 }
0189
0190 if (src == TX_RETIME_SRC_CLKGEN && freq)
0191 clk_set_rate(dwmac->clk, freq);
0192
0193 regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,
0194 stih4xx_tx_retime_val[src]);
0195 }
0196
0197 static void stid127_fix_retime_src(void *priv, u32 spd)
0198 {
0199 struct sti_dwmac *dwmac = priv;
0200 u32 reg = dwmac->ctrl_reg;
0201 u32 freq = 0;
0202 u32 val = 0;
0203
0204 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
0205 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
0206 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
0207 if (!dwmac->ext_phyclk) {
0208 val = STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK;
0209 freq = DWMAC_50MHZ;
0210 }
0211 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
0212 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
0213 if (spd == SPEED_1000)
0214 freq = DWMAC_125MHZ;
0215 else if (spd == SPEED_100)
0216 freq = DWMAC_25MHZ;
0217 else if (spd == SPEED_10)
0218 freq = DWMAC_2_5MHZ;
0219 }
0220
0221 if (freq)
0222 clk_set_rate(dwmac->clk, freq);
0223
0224 regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
0225 }
0226
0227 static int sti_dwmac_set_mode(struct sti_dwmac *dwmac)
0228 {
0229 struct regmap *regmap = dwmac->regmap;
0230 int iface = dwmac->interface;
0231 u32 reg = dwmac->ctrl_reg;
0232 u32 val;
0233
0234 if (dwmac->gmac_en)
0235 regmap_update_bits(regmap, reg, EN_MASK, EN);
0236
0237 regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
0238
0239 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
0240 regmap_update_bits(regmap, reg, ENMII_MASK, val);
0241
0242 dwmac->fix_retime_src(dwmac, dwmac->speed);
0243
0244 return 0;
0245 }
0246
0247 static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
0248 struct platform_device *pdev)
0249 {
0250 struct resource *res;
0251 struct device *dev = &pdev->dev;
0252 struct device_node *np = dev->of_node;
0253 struct regmap *regmap;
0254 int err;
0255
0256
0257 dwmac->clk_sel_reg = -ENXIO;
0258 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
0259 if (res)
0260 dwmac->clk_sel_reg = res->start;
0261
0262 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
0263 if (IS_ERR(regmap))
0264 return PTR_ERR(regmap);
0265
0266 err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->ctrl_reg);
0267 if (err) {
0268 dev_err(dev, "Can't get sysconfig ctrl offset (%d)\n", err);
0269 return err;
0270 }
0271
0272 err = of_get_phy_mode(np, &dwmac->interface);
0273 if (err && err != -ENODEV) {
0274 dev_err(dev, "Can't get phy-mode\n");
0275 return err;
0276 }
0277
0278 dwmac->regmap = regmap;
0279 dwmac->gmac_en = of_property_read_bool(np, "st,gmac_en");
0280 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
0281 dwmac->tx_retime_src = TX_RETIME_SRC_NA;
0282 dwmac->speed = SPEED_100;
0283
0284 if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
0285 const char *rs;
0286
0287 dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
0288
0289 err = of_property_read_string(np, "st,tx-retime-src", &rs);
0290 if (err < 0) {
0291 dev_warn(dev, "Use internal clock source\n");
0292 } else {
0293 if (!strcasecmp(rs, "clk_125"))
0294 dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
0295 else if (!strcasecmp(rs, "txclk"))
0296 dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
0297 }
0298 dwmac->speed = SPEED_1000;
0299 }
0300
0301 dwmac->clk = devm_clk_get(dev, "sti-ethclk");
0302 if (IS_ERR(dwmac->clk)) {
0303 dev_warn(dev, "No phy clock provided...\n");
0304 dwmac->clk = NULL;
0305 }
0306
0307 return 0;
0308 }
0309
0310 static int sti_dwmac_probe(struct platform_device *pdev)
0311 {
0312 struct plat_stmmacenet_data *plat_dat;
0313 const struct sti_dwmac_of_data *data;
0314 struct stmmac_resources stmmac_res;
0315 struct sti_dwmac *dwmac;
0316 int ret;
0317
0318 data = of_device_get_match_data(&pdev->dev);
0319 if (!data) {
0320 dev_err(&pdev->dev, "No OF match data provided\n");
0321 return -EINVAL;
0322 }
0323
0324 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
0325 if (ret)
0326 return ret;
0327
0328 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
0329 if (IS_ERR(plat_dat))
0330 return PTR_ERR(plat_dat);
0331
0332 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
0333 if (!dwmac) {
0334 ret = -ENOMEM;
0335 goto err_remove_config_dt;
0336 }
0337
0338 ret = sti_dwmac_parse_data(dwmac, pdev);
0339 if (ret) {
0340 dev_err(&pdev->dev, "Unable to parse OF data\n");
0341 goto err_remove_config_dt;
0342 }
0343
0344 dwmac->fix_retime_src = data->fix_retime_src;
0345
0346 plat_dat->bsp_priv = dwmac;
0347 plat_dat->fix_mac_speed = data->fix_retime_src;
0348
0349 ret = clk_prepare_enable(dwmac->clk);
0350 if (ret)
0351 goto err_remove_config_dt;
0352
0353 ret = sti_dwmac_set_mode(dwmac);
0354 if (ret)
0355 goto disable_clk;
0356
0357 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
0358 if (ret)
0359 goto disable_clk;
0360
0361 return 0;
0362
0363 disable_clk:
0364 clk_disable_unprepare(dwmac->clk);
0365 err_remove_config_dt:
0366 stmmac_remove_config_dt(pdev, plat_dat);
0367
0368 return ret;
0369 }
0370
0371 static int sti_dwmac_remove(struct platform_device *pdev)
0372 {
0373 struct sti_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
0374 int ret = stmmac_dvr_remove(&pdev->dev);
0375
0376 clk_disable_unprepare(dwmac->clk);
0377
0378 return ret;
0379 }
0380
0381 #ifdef CONFIG_PM_SLEEP
0382 static int sti_dwmac_suspend(struct device *dev)
0383 {
0384 struct sti_dwmac *dwmac = get_stmmac_bsp_priv(dev);
0385 int ret = stmmac_suspend(dev);
0386
0387 clk_disable_unprepare(dwmac->clk);
0388
0389 return ret;
0390 }
0391
0392 static int sti_dwmac_resume(struct device *dev)
0393 {
0394 struct sti_dwmac *dwmac = get_stmmac_bsp_priv(dev);
0395
0396 clk_prepare_enable(dwmac->clk);
0397 sti_dwmac_set_mode(dwmac);
0398
0399 return stmmac_resume(dev);
0400 }
0401 #endif
0402
0403 static SIMPLE_DEV_PM_OPS(sti_dwmac_pm_ops, sti_dwmac_suspend,
0404 sti_dwmac_resume);
0405
0406 static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
0407 .fix_retime_src = stih4xx_fix_retime_src,
0408 };
0409
0410 static const struct sti_dwmac_of_data stid127_dwmac_data = {
0411 .fix_retime_src = stid127_fix_retime_src,
0412 };
0413
0414 static const struct of_device_id sti_dwmac_match[] = {
0415 { .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
0416 { .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
0417 { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
0418 { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
0419 { }
0420 };
0421 MODULE_DEVICE_TABLE(of, sti_dwmac_match);
0422
0423 static struct platform_driver sti_dwmac_driver = {
0424 .probe = sti_dwmac_probe,
0425 .remove = sti_dwmac_remove,
0426 .driver = {
0427 .name = "sti-dwmac",
0428 .pm = &sti_dwmac_pm_ops,
0429 .of_match_table = sti_dwmac_match,
0430 },
0431 };
0432 module_platform_driver(sti_dwmac_driver);
0433
0434 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@st.com>");
0435 MODULE_DESCRIPTION("STMicroelectronics DWMAC Specific Glue layer");
0436 MODULE_LICENSE("GPL");