brintos

brintos / linux-shallow public Read only

0
0
Text · 7.2 KiB · 5f5cd35 Raw
210 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */3 4#include <linux/pcs/pcs-xpcs.h>5#include <linux/mdio.h>6#include "pcs-xpcs.h"7 8/* VR_XS_PMA_MMD */9#define TXGBE_PMA_MMD			0x802010#define TXGBE_TX_GENCTL1		0x1111#define TXGBE_TX_GENCTL1_VBOOST_LVL	GENMASK(10, 8)12#define TXGBE_TX_GENCTL1_VBOOST_EN0	BIT(4)13#define TXGBE_TX_GEN_CTL2		0x1214#define TXGBE_TX_GEN_CTL2_TX0_WIDTH(v)	FIELD_PREP(GENMASK(9, 8), v)15#define TXGBE_TX_RATE_CTL		0x1416#define TXGBE_TX_RATE_CTL_TX0_RATE(v)	FIELD_PREP(GENMASK(2, 0), v)17#define TXGBE_RX_GEN_CTL2		0x3218#define TXGBE_RX_GEN_CTL2_RX0_WIDTH(v)	FIELD_PREP(GENMASK(9, 8), v)19#define TXGBE_RX_GEN_CTL3		0x3320#define TXGBE_RX_GEN_CTL3_LOS_TRSHLD0	GENMASK(2, 0)21#define TXGBE_RX_RATE_CTL		0x3422#define TXGBE_RX_RATE_CTL_RX0_RATE(v)	FIELD_PREP(GENMASK(1, 0), v)23#define TXGBE_RX_EQ_ATTN_CTL		0x3724#define TXGBE_RX_EQ_ATTN_LVL0		GENMASK(2, 0)25#define TXGBE_RX_EQ_CTL0		0x3826#define TXGBE_RX_EQ_CTL0_VGA1_GAIN(v)	FIELD_PREP(GENMASK(15, 12), v)27#define TXGBE_RX_EQ_CTL0_VGA2_GAIN(v)	FIELD_PREP(GENMASK(11, 8), v)28#define TXGBE_RX_EQ_CTL0_CTLE_POLE(v)	FIELD_PREP(GENMASK(7, 5), v)29#define TXGBE_RX_EQ_CTL0_CTLE_BOOST(v)	FIELD_PREP(GENMASK(4, 0), v)30#define TXGBE_RX_EQ_CTL4		0x3C31#define TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0	BIT(4)32#define TXGBE_RX_EQ_CTL4_CONT_ADAPT0	BIT(0)33#define TXGBE_AFE_DFE_ENABLE		0x3D34#define TXGBE_DFE_EN_0			BIT(4)35#define TXGBE_AFE_EN_0			BIT(0)36#define TXGBE_DFE_TAP_CTL0		0x3E37#define TXGBE_MPLLA_CTL0		0x5138#define TXGBE_MPLLA_CTL2		0x5339#define TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN	BIT(10)40#define TXGBE_MPLLA_CTL2_DIV10_CLK_EN	BIT(9)41#define TXGBE_MPLLA_CTL3		0x5742#define TXGBE_MISC_CTL0			0x7043#define TXGBE_MISC_CTL0_PLL		BIT(15)44#define TXGBE_MISC_CTL0_CR_PARA_SEL	BIT(14)45#define TXGBE_MISC_CTL0_RX_VREF(v)	FIELD_PREP(GENMASK(12, 8), v)46#define TXGBE_VCO_CAL_LD0		0x7247#define TXGBE_VCO_CAL_REF0		0x7648 49static int txgbe_read_pma(struct dw_xpcs *xpcs, int reg)50{51	return xpcs_read(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg);52}53 54static int txgbe_write_pma(struct dw_xpcs *xpcs, int reg, u16 val)55{56	return xpcs_write(xpcs, MDIO_MMD_PMAPMD, TXGBE_PMA_MMD + reg, val);57}58 59static void txgbe_pma_config_10gbaser(struct dw_xpcs *xpcs)60{61	int val;62 63	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x21);64	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0);65	val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1);66	val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL);67	txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val);68	txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL |69			TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF));70	txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x549);71	txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x29);72	txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, 0);73	txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, 0);74	txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(3));75	txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(3));76	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV16P5_CLK_EN |77			TXGBE_MPLLA_CTL2_DIV10_CLK_EN);78 79	txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_CTLE_POLE(2) |80			TXGBE_RX_EQ_CTL0_CTLE_BOOST(5));81	val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL);82	val &= ~TXGBE_RX_EQ_ATTN_LVL0;83	txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);84	txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0xBE);85	val = txgbe_read_pma(xpcs, TXGBE_AFE_DFE_ENABLE);86	val &= ~(TXGBE_DFE_EN_0 | TXGBE_AFE_EN_0);87	txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, val);88	val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_CTL4);89	val &= ~TXGBE_RX_EQ_CTL4_CONT_ADAPT0;90	txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, val);91}92 93static void txgbe_pma_config_1g(struct dw_xpcs *xpcs)94{95	int val;96 97	val = txgbe_read_pma(xpcs, TXGBE_TX_GENCTL1);98	val = u16_replace_bits(val, 0x5, TXGBE_TX_GENCTL1_VBOOST_LVL);99	val &= ~TXGBE_TX_GENCTL1_VBOOST_EN0;100	txgbe_write_pma(xpcs, TXGBE_TX_GENCTL1, val);101	txgbe_write_pma(xpcs, TXGBE_MISC_CTL0, TXGBE_MISC_CTL0_PLL |102			TXGBE_MISC_CTL0_CR_PARA_SEL | TXGBE_MISC_CTL0_RX_VREF(0xF));103 104	txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL0, TXGBE_RX_EQ_CTL0_VGA1_GAIN(7) |105			TXGBE_RX_EQ_CTL0_VGA2_GAIN(7) | TXGBE_RX_EQ_CTL0_CTLE_BOOST(6));106	val = txgbe_read_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL);107	val &= ~TXGBE_RX_EQ_ATTN_LVL0;108	txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);109	txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0);110	val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3);111	val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0);112	txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL3, val);113 114	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20);115	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46);116	txgbe_write_pma(xpcs, TXGBE_VCO_CAL_LD0, 0x540);117	txgbe_write_pma(xpcs, TXGBE_VCO_CAL_REF0, 0x2A);118	txgbe_write_pma(xpcs, TXGBE_AFE_DFE_ENABLE, 0);119	txgbe_write_pma(xpcs, TXGBE_RX_EQ_CTL4, TXGBE_RX_EQ_CTL4_CONT_OFF_CAN0);120	txgbe_write_pma(xpcs, TXGBE_TX_RATE_CTL, TXGBE_TX_RATE_CTL_TX0_RATE(3));121	txgbe_write_pma(xpcs, TXGBE_RX_RATE_CTL, TXGBE_RX_RATE_CTL_RX0_RATE(3));122	txgbe_write_pma(xpcs, TXGBE_TX_GEN_CTL2, TXGBE_TX_GEN_CTL2_TX0_WIDTH(1));123	txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL2, TXGBE_RX_GEN_CTL2_RX0_WIDTH(1));124	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL2, TXGBE_MPLLA_CTL2_DIV10_CLK_EN);125}126 127static int txgbe_pcs_poll_power_up(struct dw_xpcs *xpcs)128{129	int val, ret;130 131	/* Wait xpcs power-up good */132	ret = read_poll_timeout(xpcs_read_vpcs, val,133				(val & DW_PSEQ_ST) == DW_PSEQ_ST_GOOD,134				10000, 1000000, false,135				xpcs, DW_VR_XS_PCS_DIG_STS);136	if (ret < 0)137		dev_err(&xpcs->mdiodev->dev, "xpcs power-up timeout\n");138 139	return ret;140}141 142static int txgbe_pma_init_done(struct dw_xpcs *xpcs)143{144	int val, ret;145 146	xpcs_write_vpcs(xpcs, DW_VR_XS_PCS_DIG_CTRL1, DW_VR_RST | DW_EN_VSMMD1);147 148	/* wait pma initialization done */149	ret = read_poll_timeout(xpcs_read_vpcs, val, !(val & DW_VR_RST),150				100000, 10000000, false,151				xpcs, DW_VR_XS_PCS_DIG_CTRL1);152	if (ret < 0)153		dev_err(&xpcs->mdiodev->dev, "xpcs pma initialization timeout\n");154 155	return ret;156}157 158static bool txgbe_xpcs_mode_quirk(struct dw_xpcs *xpcs)159{160	int ret;161 162	/* When txgbe do LAN reset, PCS will change to default 10GBASE-R mode */163	ret = xpcs_read(xpcs, MDIO_MMD_PCS, MDIO_CTRL2);164	ret &= MDIO_PCS_CTRL2_TYPE;165	if ((ret == MDIO_PCS_CTRL2_10GBR &&166	     xpcs->interface != PHY_INTERFACE_MODE_10GBASER) ||167	    xpcs->interface == PHY_INTERFACE_MODE_SGMII)168		return true;169 170	return false;171}172 173int txgbe_xpcs_switch_mode(struct dw_xpcs *xpcs, phy_interface_t interface)174{175	int val, ret;176 177	switch (interface) {178	case PHY_INTERFACE_MODE_10GBASER:179	case PHY_INTERFACE_MODE_SGMII:180	case PHY_INTERFACE_MODE_1000BASEX:181		break;182	default:183		return 0;184	}185 186	if (xpcs->interface == interface && !txgbe_xpcs_mode_quirk(xpcs))187		return 0;188 189	xpcs->interface = interface;190 191	ret = txgbe_pcs_poll_power_up(xpcs);192	if (ret < 0)193		return ret;194 195	if (interface == PHY_INTERFACE_MODE_10GBASER) {196		xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBR);197		val = xpcs_read(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1);198		val |= MDIO_CTRL1_SPEED10G;199		xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, val);200		txgbe_pma_config_10gbaser(xpcs);201	} else {202		xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL2, MDIO_PCS_CTRL2_10GBX);203		xpcs_write(xpcs, MDIO_MMD_PMAPMD, MDIO_CTRL1, 0);204		xpcs_write(xpcs, MDIO_MMD_PCS, MDIO_CTRL1, 0);205		txgbe_pma_config_1g(xpcs);206	}207 208	return txgbe_pma_init_done(xpcs);209}210