-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: ethernet: mediatek: Extend SGMII related functions
Add SGMII related logic into a separate file, and also provides options for forcing 1G, 2.5, AN mode for the target PHY, that can be determined from SGMII node in DTS. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
1 parent
3277fc6
commit 9ffee4a
Showing
4 changed files
with
184 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (c) 2018-2019 MediaTek Inc. | ||
|
||
/* A library for MediaTek SGMII circuit | ||
* | ||
* Author: Sean Wang <sean.wang@mediatek.com> | ||
* | ||
*/ | ||
|
||
#include <linux/mfd/syscon.h> | ||
#include <linux/of.h> | ||
#include <linux/regmap.h> | ||
|
||
#include "mtk_eth_soc.h" | ||
|
||
int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) | ||
{ | ||
struct device_node *np; | ||
const char *str; | ||
int i, err; | ||
|
||
ss->ana_rgc3 = ana_rgc3; | ||
|
||
for (i = 0; i < MTK_MAX_DEVS; i++) { | ||
np = of_parse_phandle(r, "mediatek,sgmiisys", i); | ||
if (!np) | ||
break; | ||
|
||
ss->regmap[i] = syscon_node_to_regmap(np); | ||
if (IS_ERR(ss->regmap[i])) | ||
return PTR_ERR(ss->regmap[i]); | ||
|
||
err = of_property_read_string(np, "mediatek,physpeed", &str); | ||
if (err) | ||
return err; | ||
|
||
if (!strcmp(str, "2500")) | ||
ss->flags[i] |= MTK_SGMII_PHYSPEED_2500; | ||
else if (!strcmp(str, "1000")) | ||
ss->flags[i] |= MTK_SGMII_PHYSPEED_1000; | ||
else if (!strcmp(str, "auto")) | ||
ss->flags[i] |= MTK_SGMII_PHYSPEED_AN; | ||
else | ||
return -EINVAL; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) | ||
{ | ||
unsigned int val; | ||
|
||
if (!ss->regmap[id]) | ||
return -EINVAL; | ||
|
||
/* Setup the link timer and QPHY power up inside SGMIISYS */ | ||
regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER, | ||
SGMII_LINK_TIMER_DEFAULT); | ||
|
||
regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); | ||
val |= SGMII_REMOTE_FAULT_DIS; | ||
regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); | ||
|
||
regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); | ||
val |= SGMII_AN_RESTART; | ||
regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); | ||
|
||
regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); | ||
val &= ~SGMII_PHYA_PWD; | ||
regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); | ||
|
||
return 0; | ||
} | ||
|
||
int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id) | ||
{ | ||
unsigned int val; | ||
int mode; | ||
|
||
if (!ss->regmap[id]) | ||
return -EINVAL; | ||
|
||
regmap_read(ss->regmap[id], ss->ana_rgc3, &val); | ||
val &= ~GENMASK(2, 3); | ||
mode = ss->flags[id] & MTK_SGMII_PHYSPEED_MASK; | ||
val |= (mode == MTK_SGMII_PHYSPEED_1000) ? 0 : BIT(2); | ||
regmap_write(ss->regmap[id], ss->ana_rgc3, val); | ||
|
||
/* Disable SGMII AN */ | ||
regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); | ||
val &= ~BIT(12); | ||
regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); | ||
|
||
/* SGMII force mode setting */ | ||
val = 0x31120019; | ||
regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); | ||
|
||
/* Release PHYA power down state */ | ||
regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); | ||
val &= ~SGMII_PHYA_PWD; | ||
regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); | ||
|
||
return 0; | ||
} |