1 // SPDX-License-Identifier: GPL-2.0+
3 * StarFive DWMAC platform driver
5 * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
6 * Copyright (C) 2022 StarFive Technology Co., Ltd.
10 #include <linux/mfd/syscon.h>
11 #include <linux/of_device.h>
12 #include <linux/regmap.h>
14 #include "stmmac_platform.h"
16 struct starfive_dwmac {
21 static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
23 struct starfive_dwmac *dwmac = priv;
38 dev_err(dwmac->dev, "invalid speed %u\n", speed);
42 err = clk_set_rate(dwmac->clk_tx, rate);
44 dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
47 static int starfive_dwmac_probe(struct platform_device *pdev)
49 struct plat_stmmacenet_data *plat_dat;
50 struct stmmac_resources stmmac_res;
51 struct starfive_dwmac *dwmac;
55 err = stmmac_get_platform_resources(pdev, &stmmac_res);
59 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
60 if (IS_ERR(plat_dat)) {
61 dev_err(&pdev->dev, "dt configuration failed\n");
62 return PTR_ERR(plat_dat);
65 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
69 dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
70 if (IS_ERR(dwmac->clk_tx))
71 return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
72 "error getting tx clock\n");
74 clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
76 return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
77 "error getting gtx clock\n");
79 /* Generally, the rgmii_tx clock is provided by the internal clock,
80 * which needs to match the corresponding clock frequency according
81 * to different speeds. If the rgmii_tx clock is provided by the
82 * external rgmii_rxin, there is no need to configure the clock
83 * internally, because rgmii_rxin will be adaptively adjusted.
85 if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
86 plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;
88 dwmac->dev = &pdev->dev;
89 plat_dat->bsp_priv = dwmac;
90 plat_dat->dma_cfg->dche = true;
92 err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
94 stmmac_remove_config_dt(pdev, plat_dat);
101 static const struct of_device_id starfive_dwmac_match[] = {
102 { .compatible = "starfive,jh7110-dwmac" },
105 MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
107 static struct platform_driver starfive_dwmac_driver = {
108 .probe = starfive_dwmac_probe,
109 .remove = stmmac_pltfr_remove,
111 .name = "starfive-dwmac",
112 .pm = &stmmac_pltfr_pm_ops,
113 .of_match_table = starfive_dwmac_match,
116 module_platform_driver(starfive_dwmac_driver);
118 MODULE_LICENSE("GPL");
119 MODULE_DESCRIPTION("StarFive DWMAC platform driver");
120 MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
121 MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");