|
@@ -185,7 +185,8 @@ static void mtk_phy_link_adjust(struct net_device *dev)
|
|
|
break;
|
|
|
};
|
|
|
|
|
|
- if (mac->id == 0 && !mac->trgmii)
|
|
|
+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_GMAC1_TRGMII) &&
|
|
|
+ !mac->id && !mac->trgmii)
|
|
|
mtk_gmac0_rgmii_adjust(mac->hw, dev->phydev->speed);
|
|
|
|
|
|
if (dev->phydev->link)
|
|
@@ -1834,9 +1835,36 @@ static void ethsys_reset(struct mtk_eth *eth, u32 reset_bits)
|
|
|
mdelay(10);
|
|
|
}
|
|
|
|
|
|
+static void mtk_clk_disable(struct mtk_eth *eth)
|
|
|
+{
|
|
|
+ int clk;
|
|
|
+
|
|
|
+ for (clk = MTK_CLK_MAX - 1; clk >= 0; clk--)
|
|
|
+ clk_disable_unprepare(eth->clks[clk]);
|
|
|
+}
|
|
|
+
|
|
|
+static int mtk_clk_enable(struct mtk_eth *eth)
|
|
|
+{
|
|
|
+ int clk, ret;
|
|
|
+
|
|
|
+ for (clk = 0; clk < MTK_CLK_MAX ; clk++) {
|
|
|
+ ret = clk_prepare_enable(eth->clks[clk]);
|
|
|
+ if (ret)
|
|
|
+ goto err_disable_clks;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_disable_clks:
|
|
|
+ while (--clk >= 0)
|
|
|
+ clk_disable_unprepare(eth->clks[clk]);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static int mtk_hw_init(struct mtk_eth *eth)
|
|
|
{
|
|
|
- int i, val;
|
|
|
+ int i, val, ret;
|
|
|
|
|
|
if (test_and_set_bit(MTK_HW_INIT, ð->state))
|
|
|
return 0;
|
|
@@ -1844,10 +1872,10 @@ static int mtk_hw_init(struct mtk_eth *eth)
|
|
|
pm_runtime_enable(eth->dev);
|
|
|
pm_runtime_get_sync(eth->dev);
|
|
|
|
|
|
- clk_prepare_enable(eth->clks[MTK_CLK_ETHIF]);
|
|
|
- clk_prepare_enable(eth->clks[MTK_CLK_ESW]);
|
|
|
- clk_prepare_enable(eth->clks[MTK_CLK_GP1]);
|
|
|
- clk_prepare_enable(eth->clks[MTK_CLK_GP2]);
|
|
|
+ ret = mtk_clk_enable(eth);
|
|
|
+ if (ret)
|
|
|
+ goto err_disable_pm;
|
|
|
+
|
|
|
ethsys_reset(eth, RSTCTRL_FE);
|
|
|
ethsys_reset(eth, RSTCTRL_PPE);
|
|
|
|
|
@@ -1915,6 +1943,12 @@ static int mtk_hw_init(struct mtk_eth *eth)
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
+
|
|
|
+err_disable_pm:
|
|
|
+ pm_runtime_put_sync(eth->dev);
|
|
|
+ pm_runtime_disable(eth->dev);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int mtk_hw_deinit(struct mtk_eth *eth)
|
|
@@ -1922,10 +1956,7 @@ static int mtk_hw_deinit(struct mtk_eth *eth)
|
|
|
if (!test_and_clear_bit(MTK_HW_INIT, ð->state))
|
|
|
return 0;
|
|
|
|
|
|
- clk_disable_unprepare(eth->clks[MTK_CLK_GP2]);
|
|
|
- clk_disable_unprepare(eth->clks[MTK_CLK_GP1]);
|
|
|
- clk_disable_unprepare(eth->clks[MTK_CLK_ESW]);
|
|
|
- clk_disable_unprepare(eth->clks[MTK_CLK_ETHIF]);
|
|
|
+ mtk_clk_disable(eth);
|
|
|
|
|
|
pm_runtime_put_sync(eth->dev);
|
|
|
pm_runtime_disable(eth->dev);
|
|
@@ -2403,6 +2434,7 @@ static int mtk_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
struct device_node *mac_np;
|
|
|
+ const struct of_device_id *match;
|
|
|
struct mtk_eth *eth;
|
|
|
int err;
|
|
|
int i;
|
|
@@ -2411,6 +2443,9 @@ static int mtk_probe(struct platform_device *pdev)
|
|
|
if (!eth)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ match = of_match_device(of_mtk_match, &pdev->dev);
|
|
|
+ eth->soc = (struct mtk_soc_data *)match->data;
|
|
|
+
|
|
|
eth->dev = &pdev->dev;
|
|
|
eth->base = devm_ioremap_resource(&pdev->dev, res);
|
|
|
if (IS_ERR(eth->base))
|
|
@@ -2447,7 +2482,12 @@ static int mtk_probe(struct platform_device *pdev)
|
|
|
if (IS_ERR(eth->clks[i])) {
|
|
|
if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
|
|
|
return -EPROBE_DEFER;
|
|
|
- return -ENODEV;
|
|
|
+ if (eth->soc->required_clks & BIT(i)) {
|
|
|
+ dev_err(&pdev->dev, "clock %s not found\n",
|
|
|
+ mtk_clks_source_name[i]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ eth->clks[i] = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2550,8 +2590,19 @@ static int mtk_remove(struct platform_device *pdev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static const struct mtk_soc_data mt2701_data = {
|
|
|
+ .caps = MTK_GMAC1_TRGMII,
|
|
|
+ .required_clks = MT7623_CLKS_BITMAP
|
|
|
+};
|
|
|
+
|
|
|
+static const struct mtk_soc_data mt7623_data = {
|
|
|
+ .caps = MTK_GMAC1_TRGMII,
|
|
|
+ .required_clks = MT7623_CLKS_BITMAP
|
|
|
+};
|
|
|
+
|
|
|
const struct of_device_id of_mtk_match[] = {
|
|
|
- { .compatible = "mediatek,mt2701-eth" },
|
|
|
+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
|
|
|
+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
|
|
{},
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(of, of_mtk_match);
|