Lines Matching +full:dwmac +full:- +full:mdio

1 // SPDX-License-Identifier: GPL-2.0-only
4 * Adopted from dwmac-sti.c
7 #include <linux/mfd/altera-sysmgr.h>
13 #include <linux/mdio/mdio-regmap.h>
14 #include <linux/pcs-lynx.h>
66 struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv; in socfpga_dwmac_fix_mac_speed() local
67 void __iomem *splitter_base = dwmac->splitter_base; in socfpga_dwmac_fix_mac_speed()
68 void __iomem *sgmii_adapter_base = dwmac->sgmii_adapter_base; in socfpga_dwmac_fix_mac_speed()
69 struct device *dev = dwmac->dev; in socfpga_dwmac_fix_mac_speed()
71 struct phy_device *phy_dev = ndev->phydev; in socfpga_dwmac_fix_mac_speed()
103 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) in socfpga_dwmac_parse_data() argument
105 struct device_node *np = dev->of_node; in socfpga_dwmac_parse_data()
116 altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); in socfpga_dwmac_parse_data()
118 dev_info(dev, "No sysmgr-syscon node found\n"); in socfpga_dwmac_parse_data()
122 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset); in socfpga_dwmac_parse_data()
124 dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); in socfpga_dwmac_parse_data()
125 return -EINVAL; in socfpga_dwmac_parse_data()
128 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift); in socfpga_dwmac_parse_data()
130 dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); in socfpga_dwmac_parse_data()
131 return -EINVAL; in socfpga_dwmac_parse_data()
134 dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk"); in socfpga_dwmac_parse_data()
136 np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0); in socfpga_dwmac_parse_data()
142 return -EINVAL; in socfpga_dwmac_parse_data()
145 dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); in socfpga_dwmac_parse_data()
146 if (IS_ERR(dwmac->splitter_base)) { in socfpga_dwmac_parse_data()
148 return PTR_ERR(dwmac->splitter_base); in socfpga_dwmac_parse_data()
153 "altr,gmii-to-sgmii-converter", 0); in socfpga_dwmac_parse_data()
155 index = of_property_match_string(np_sgmii_adapter, "reg-names", in socfpga_dwmac_parse_data()
164 ret = -EINVAL; in socfpga_dwmac_parse_data()
168 dwmac->splitter_base = in socfpga_dwmac_parse_data()
171 if (IS_ERR(dwmac->splitter_base)) { in socfpga_dwmac_parse_data()
172 ret = PTR_ERR(dwmac->splitter_base); in socfpga_dwmac_parse_data()
177 index = of_property_match_string(np_sgmii_adapter, "reg-names", in socfpga_dwmac_parse_data()
186 ret = -EINVAL; in socfpga_dwmac_parse_data()
190 dwmac->sgmii_adapter_base = in socfpga_dwmac_parse_data()
193 if (IS_ERR(dwmac->sgmii_adapter_base)) { in socfpga_dwmac_parse_data()
194 ret = PTR_ERR(dwmac->sgmii_adapter_base); in socfpga_dwmac_parse_data()
199 index = of_property_match_string(np_sgmii_adapter, "reg-names", in socfpga_dwmac_parse_data()
208 ret = -EINVAL; in socfpga_dwmac_parse_data()
212 dwmac->tse_pcs_base = in socfpga_dwmac_parse_data()
215 if (IS_ERR(dwmac->tse_pcs_base)) { in socfpga_dwmac_parse_data()
216 ret = PTR_ERR(dwmac->tse_pcs_base); in socfpga_dwmac_parse_data()
221 dwmac->reg_offset = reg_offset; in socfpga_dwmac_parse_data()
222 dwmac->reg_shift = reg_shift; in socfpga_dwmac_parse_data()
223 dwmac->sys_mgr_base_addr = sys_mgr_base_addr; in socfpga_dwmac_parse_data()
224 dwmac->dev = dev; in socfpga_dwmac_parse_data()
234 static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac) in socfpga_get_plat_phymode() argument
236 struct net_device *ndev = dev_get_drvdata(dwmac->dev); in socfpga_get_plat_phymode()
239 return priv->plat->mac_interface; in socfpga_get_plat_phymode()
242 static void socfpga_sgmii_config(struct socfpga_dwmac *dwmac, bool enable) in socfpga_sgmii_config() argument
246 writew(val, dwmac->sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); in socfpga_sgmii_config()
267 return -EINVAL; in socfpga_set_phy_mode_common()
272 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac) in socfpga_gen5_set_phy_mode() argument
274 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; in socfpga_gen5_set_phy_mode()
275 int phymode = socfpga_get_plat_phymode(dwmac); in socfpga_gen5_set_phy_mode()
276 u32 reg_offset = dwmac->reg_offset; in socfpga_gen5_set_phy_mode()
277 u32 reg_shift = dwmac->reg_shift; in socfpga_gen5_set_phy_mode()
281 dev_err(dwmac->dev, "bad phy mode %d\n", phymode); in socfpga_gen5_set_phy_mode()
282 return -EINVAL; in socfpga_gen5_set_phy_mode()
289 if (dwmac->splitter_base) in socfpga_gen5_set_phy_mode()
293 reset_control_assert(dwmac->stmmac_ocp_rst); in socfpga_gen5_set_phy_mode()
294 reset_control_assert(dwmac->stmmac_rst); in socfpga_gen5_set_phy_mode()
300 if (dwmac->f2h_ptp_ref_clk || in socfpga_gen5_set_phy_mode()
311 if (dwmac->f2h_ptp_ref_clk) in socfpga_gen5_set_phy_mode()
322 reset_control_deassert(dwmac->stmmac_ocp_rst); in socfpga_gen5_set_phy_mode()
323 reset_control_deassert(dwmac->stmmac_rst); in socfpga_gen5_set_phy_mode()
325 socfpga_sgmii_config(dwmac, true); in socfpga_gen5_set_phy_mode()
330 static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac) in socfpga_gen10_set_phy_mode() argument
332 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; in socfpga_gen10_set_phy_mode()
333 int phymode = socfpga_get_plat_phymode(dwmac); in socfpga_gen10_set_phy_mode()
334 u32 reg_offset = dwmac->reg_offset; in socfpga_gen10_set_phy_mode()
335 u32 reg_shift = dwmac->reg_shift; in socfpga_gen10_set_phy_mode()
339 return -EINVAL; in socfpga_gen10_set_phy_mode()
345 if (dwmac->splitter_base) in socfpga_gen10_set_phy_mode()
349 reset_control_assert(dwmac->stmmac_ocp_rst); in socfpga_gen10_set_phy_mode()
350 reset_control_assert(dwmac->stmmac_rst); in socfpga_gen10_set_phy_mode()
356 if (dwmac->f2h_ptp_ref_clk || in socfpga_gen10_set_phy_mode()
375 reset_control_deassert(dwmac->stmmac_ocp_rst); in socfpga_gen10_set_phy_mode()
376 reset_control_deassert(dwmac->stmmac_rst); in socfpga_gen10_set_phy_mode()
378 socfpga_sgmii_config(dwmac, true); in socfpga_gen10_set_phy_mode()
384 struct socfpga_dwmac *dwmac = priv->plat->bsp_priv; in socfpga_dwmac_pcs_init() local
395 if (!dwmac->tse_pcs_base) in socfpga_dwmac_pcs_init()
398 pcs_regmap = devm_regmap_init_mmio(priv->device, dwmac->tse_pcs_base, in socfpga_dwmac_pcs_init()
405 mrc.parent = priv->device; in socfpga_dwmac_pcs_init()
409 /* Can't use ndev->name here because it will not have been initialised, in socfpga_dwmac_pcs_init()
412 snprintf(mrc.name, MII_BUS_ID_SIZE, "%s-pcs-mii", in socfpga_dwmac_pcs_init()
413 dev_name(priv->device)); in socfpga_dwmac_pcs_init()
414 pcs_bus = devm_mdio_regmap_register(priv->device, &mrc); in socfpga_dwmac_pcs_init()
422 priv->hw->phylink_pcs = pcs; in socfpga_dwmac_pcs_init()
428 if (priv->hw->phylink_pcs) in socfpga_dwmac_pcs_exit()
429 lynx_pcs_destroy(priv->hw->phylink_pcs); in socfpga_dwmac_pcs_exit()
435 return priv->hw->phylink_pcs; in socfpga_dwmac_select_pcs()
442 struct device *dev = &pdev->dev; in socfpga_dwmac_probe()
444 struct socfpga_dwmac *dwmac; in socfpga_dwmac_probe() local
449 ops = device_get_match_data(&pdev->dev); in socfpga_dwmac_probe()
451 dev_err(&pdev->dev, "no of match data provided\n"); in socfpga_dwmac_probe()
452 return -EINVAL; in socfpga_dwmac_probe()
463 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL); in socfpga_dwmac_probe()
464 if (!dwmac) in socfpga_dwmac_probe()
465 return -ENOMEM; in socfpga_dwmac_probe()
467 dwmac->stmmac_ocp_rst = devm_reset_control_get_optional(dev, "stmmaceth-ocp"); in socfpga_dwmac_probe()
468 if (IS_ERR(dwmac->stmmac_ocp_rst)) { in socfpga_dwmac_probe()
469 ret = PTR_ERR(dwmac->stmmac_ocp_rst); in socfpga_dwmac_probe()
474 reset_control_deassert(dwmac->stmmac_ocp_rst); in socfpga_dwmac_probe()
476 ret = socfpga_dwmac_parse_data(dwmac, dev); in socfpga_dwmac_probe()
482 dwmac->ops = ops; in socfpga_dwmac_probe()
483 plat_dat->bsp_priv = dwmac; in socfpga_dwmac_probe()
484 plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; in socfpga_dwmac_probe()
485 plat_dat->pcs_init = socfpga_dwmac_pcs_init; in socfpga_dwmac_probe()
486 plat_dat->pcs_exit = socfpga_dwmac_pcs_exit; in socfpga_dwmac_probe()
487 plat_dat->select_pcs = socfpga_dwmac_select_pcs; in socfpga_dwmac_probe()
489 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); in socfpga_dwmac_probe()
500 dwmac->stmmac_rst = stpriv->plat->stmmac_rst; in socfpga_dwmac_probe()
502 ret = ops->set_phy_mode(dwmac); in socfpga_dwmac_probe()
509 stmmac_dvr_remove(&pdev->dev); in socfpga_dwmac_probe()
521 dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv); in socfpga_dwmac_resume()
538 if (ndev->phydev) in socfpga_dwmac_resume()
539 phy_resume(ndev->phydev); in socfpga_dwmac_resume()
577 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops },
578 { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops },
587 .name = "socfpga-dwmac",
594 MODULE_DESCRIPTION("Altera SOC DWMAC Specific Glue layer");