diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c index 9af9035..9caab92 100644 --- a/drivers/net/pcs/pcs-mtk-usxgmii.c +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c @@ -52,6 +52,12 @@ #define USXGMII_LPA GENMASK(15, 0) #define USXGMII_LPA_LATCH BIT(31) +/* Register to control PCS polarity */ +#define RG_PHY_TOP_CTRL0 0x82C +#define USXGMII_PN_SWAP_MASK GENMASK(1, 0) +#define USXGMII_PN_SWAP_RX BIT(1) +#define USXGMII_PN_SWAP_TX BIT(0) + /* Register to read PCS link status */ #define RG_PCS_RX_STATUS0 0x904 #define RG_PCS_RX_STATUS_UPDATE BIT(16) @@ -74,6 +80,7 @@ struct mtk_usxgmii_pcs { struct clk *clk; struct reset_control *reset; phy_interface_t interface; + unsigned int polarity; unsigned int neg_mode; struct list_head node; }; @@ -155,6 +162,10 @@ static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode mtk_usxgmii_reset(mpcs); + /* Configure the interface polarity */ + mtk_m32(mpcs, RG_PHY_TOP_CTRL0, + USXGMII_PN_SWAP_MASK, mpcs->polarity); + /* Setup USXGMII AN ctrl */ mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, @@ -332,6 +343,7 @@ static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { static int mtk_usxgmii_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct mtk_usxgmii_pcs *mpcs; mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); @@ -342,6 +354,13 @@ static int mtk_usxgmii_probe(struct platform_device *pdev) if (IS_ERR(mpcs->base)) return PTR_ERR(mpcs->base); + if (of_property_read_bool(np->parent, "mediatek,pnswap")) + mpcs->polarity = USXGMII_PN_SWAP_TX | USXGMII_PN_SWAP_RX; + else if (of_property_read_bool(np, "mediatek,pnswap-tx")) + mpcs->polarity = USXGMII_PN_SWAP_TX; + else if (of_property_read_bool(np, "mediatek,pnswap-rx")) + mpcs->polarity = USXGMII_PN_SWAP_RX; + mpcs->dev = dev; mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; mpcs->pcs.poll = true;