[][Add MT7531 phy setting to dsa driver]

[Description]
Add MT7531 phy setting to dsa driver including
1. Disable EEE in default.
2. Adjust line driving for better link quality.
3. Adjust 100M eye diagram for compliance test.
4. Enable link down power saving.
5. Enable auto down shift from 1G to 100M if 1G signal is unstable.
6. SW phy calibration is disabled, and use calibration data in efuse.

[Release-log]
Add MT7531 phy setting to dsa driver including
1. Disable EEE in default.
2. Adjust line driving for better link quality.
3. Adjust 100M eye diagram for compliance test.
4. Enable link down power saving.
5. Enable auto down shift from 1G to 100M if 1G signal is unstable.

Change-Id: Id67a66e853dec76428961b2bc25c495f16f246d5
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/4720227
diff --git a/target/linux/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch b/target/linux/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
new file mode 100644
index 0000000..ca7e083
--- /dev/null
+++ b/target/linux/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
@@ -0,0 +1,1687 @@
+Index: linux-5.4.124/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-5.4.124.orig/drivers/net/dsa/mt7530.c
++++ linux-5.4.124/drivers/net/dsa/mt7530.c
+@@ -1830,6 +1830,8 @@ mt7531_setup(struct dsa_switch *ds)
+ 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+ 	}
+ 
++	mt7531_phy_setup(ds);
++
+ 	/* Group and enable unused ports as a standalone dumb switch. */
+ 	setup_unused_ports(ds, unused_pm);
+ 
+Index: linux-5.4.124/drivers/net/dsa/mt7530.h
+===================================================================
+--- linux-5.4.124.orig/drivers/net/dsa/mt7530.h
++++ linux-5.4.124/drivers/net/dsa/mt7530.h
+@@ -782,4 +782,5 @@ static inline void INIT_MT7530_DUMMY_POL
+ 	p->reg = reg;
+ }
+ 
++int mt7531_phy_setup(struct dsa_switch *ds);
+ #endif /* __MT7530_H */
+Index: linux-5.4.124/drivers/net/dsa/mt7531_phy.c
+===================================================================
+--- /dev/null
++++ linux-5.4.124/drivers/net/dsa/mt7531_phy.c
+@@ -0,0 +1,1378 @@
++// SPDX-License-Identifier:	GPL-2.0+
++/*
++ * Common part for MediaTek MT753x gigabit switch
++ *
++ * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
++ *
++ * Author: Weijie Gao <weijie.gao@mediatek.com>
++ */
++
++#include <linux/delay.h>
++#include <linux/hrtimer.h>
++#include <linux/kernel.h>
++#include <net/dsa.h>
++#include "mt7530.h"
++#include "mt7531_phy.h"
++
++#define MT7531_NUM_PHYS 5
++
++static u32 tc_phy_read_dev_reg(struct dsa_switch *ds, u32 port_num, u32 dev_addr, u32 reg_addr)
++{
++	struct mt7530_priv *priv = ds->priv;
++	u32 phy_val;
++	u32 addr;
++
++	addr = MII_ADDR_C45 | (dev_addr << 16) | (reg_addr & 0xffff);
++	phy_val = priv->info->phy_read(ds, port_num, addr);
++
++	//printk("switch phy cl45 r %d 0x%x 0x%x = %x\n",port_num, dev_addr, reg_addr, phy_val);
++	return phy_val;
++}
++
++static void tc_phy_write_dev_reg(struct dsa_switch *ds, u32 port_num, u32 dev_addr, u32 reg_addr, u32 write_data)
++{
++	struct mt7530_priv *priv = ds->priv;
++	u32 addr;
++
++	addr = MII_ADDR_C45 | (dev_addr << 16) | (reg_addr & 0xffff);
++
++	priv->info->phy_write(ds, port_num, addr, write_data);
++
++	//u32 phy_val = priv->info->phy_read(ds, port_num, addr);
++	//printk("switch phy cl45 w %d 0x%x 0x%x 0x%x --> read back 0x%x\n",port_num, dev_addr, reg_addr, write_data, phy_val);
++}
++
++static void switch_phy_write(struct dsa_switch *ds, u32 port_num, u32 reg_addr, u32 write_data){
++	struct mt7530_priv *priv = ds->priv;
++
++	priv->info->phy_write(ds, port_num, reg_addr, write_data);
++}
++
++static u32 switch_phy_read(struct dsa_switch *ds, u32 port_num, u32 reg_addr){
++	struct mt7530_priv *priv = ds->priv;
++
++	return priv->info->phy_read(ds, port_num, reg_addr);
++}
++
++static void mt753x_tr_write(struct dsa_switch *ds, int addr, u8 ch, u8 node, u8 daddr,
++		     u32 data)
++{
++	ktime_t timeout;
++	u32 timeout_us;
++	u32 val;
++
++	switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);
++
++	val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++	timeout_us = 100000;
++	timeout = ktime_add_us(ktime_get(), timeout_us);
++	while (1) {
++		val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++		if (!!(val & PHY_TR_PKT_XMT_STA))
++			break;
++
++		if (ktime_compare(ktime_get(), timeout) > 0)
++			goto out;
++	}
++
++	switch_phy_write(ds, addr, PHY_TR_LOW_DATA, PHY_TR_LOW_VAL(data));
++	switch_phy_write(ds, addr, PHY_TR_HIGH_DATA, PHY_TR_HIGH_VAL(data));
++	val = PHY_TR_PKT_XMT_STA | (PHY_TR_WRITE << PHY_TR_WR_S) |
++	      (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
++	      (daddr << PHY_TR_DATA_ADDR_S);
++	switch_phy_write(ds, addr, PHY_TR_CTRL, val);
++
++	timeout_us = 100000;
++	timeout = ktime_add_us(ktime_get(), timeout_us);
++	while (1) {
++		val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++		if (!!(val & PHY_TR_PKT_XMT_STA))
++			break;
++
++		if (ktime_compare(ktime_get(), timeout) > 0)
++			goto out;
++	}
++out:
++	switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
++}
++
++static int mt753x_tr_read(struct dsa_switch *ds, int addr, u8 ch, u8 node, u8 daddr)
++{
++	ktime_t timeout;
++	u32 timeout_us;
++	u32 val;
++	u8 val_h;
++
++	switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);
++
++	val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++	timeout_us = 100000;
++	timeout = ktime_add_us(ktime_get(), timeout_us);
++	while (1) {
++		val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++		if (!!(val & PHY_TR_PKT_XMT_STA))
++			break;
++
++		if (ktime_compare(ktime_get(), timeout) > 0) {
++			switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
++			return -ETIMEDOUT;
++		}
++	}
++
++	val = PHY_TR_PKT_XMT_STA | (PHY_TR_READ << PHY_TR_WR_S) |
++	      (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
++	      (daddr << PHY_TR_DATA_ADDR_S);
++	switch_phy_write(ds, addr, PHY_TR_CTRL, val);
++
++	timeout_us = 100000;
++	timeout = ktime_add_us(ktime_get(), timeout_us);
++	while (1) {
++		val = switch_phy_read(ds, addr, PHY_TR_CTRL);
++
++		if (!!(val & PHY_TR_PKT_XMT_STA))
++			break;
++
++		if (ktime_compare(ktime_get(), timeout) > 0) {
++			switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
++			return -ETIMEDOUT;
++		}
++	}
++
++	val = switch_phy_read(ds, addr, PHY_TR_LOW_DATA);
++	val_h = switch_phy_read(ds, addr, PHY_TR_HIGH_DATA);
++	val |= (val_h << 16);
++
++	switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
++
++	return val;
++}
++
++static const u8 MT753x_ZCAL_TO_R50ohm_GE_TBL_100[64] = {
++	127, 127, 127, 127, 127, 127, 127, 127,
++	127, 127, 127, 127, 127, 123, 122, 117,
++	115, 112, 103, 100, 98, 87, 85, 83,
++	81, 72, 70, 68, 66, 64, 55, 53,
++	52, 50, 49, 48, 38, 36, 35, 34,
++	33, 32, 22, 21, 20, 19, 18, 17,
++	16, 7, 6, 5, 4, 3, 2, 1,
++	0, 0, 0, 0, 0, 0, 0, 0
++};
++
++static const u8 MT753x_TX_OFFSET_TBL[64] = {
++	0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
++	0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
++	0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,
++	0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
++	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
++	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
++	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
++	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
++};
++
++static u8 ge_cal_flag;
++
++static u8 all_ge_ana_cal_wait(struct dsa_switch *ds, u32 delay, u32 phyaddr)
++{
++	u8 all_ana_cal_status;
++	u32 cnt, tmp_1e_17c;
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017c, 0x0001);	// da_calin_flag pull high
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
++	//printk("delay = %d\n", delay);
++
++	cnt = 10000;
++	do {
++		udelay(delay);
++		cnt--;
++		all_ana_cal_status = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17b) & 0x1;
++
++	} while ((all_ana_cal_status == 0) && (cnt != 0));
++
++
++	if(all_ana_cal_status == 1) {
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
++		return all_ana_cal_status;
++	} else {
++		tmp_1e_17c = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c);
++		if ((tmp_1e_17c & 0x1) != 1) {
++			pr_info("FIRST MDC/MDIO write error\n");
++			pr_info("FIRST 1e_17c = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c));
++
++		}
++		printk("re-K again\n");
++
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
++		cnt = 10000;
++		do {
++			udelay(delay);
++			cnt--;
++			tmp_1e_17c = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c);
++			if ((tmp_1e_17c & 0x1) != 1) {
++				pr_info("SECOND MDC/MDIO write error\n");
++				pr_info("SECOND 1e_17c = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c));
++				tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
++				tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
++				tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
++			}
++		} while ((cnt != 0) && (tmp_1e_17c == 0));
++
++		cnt = 10000;
++		do {
++			udelay(delay);
++			cnt--;
++			all_ana_cal_status = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17b) & 0x1;
++
++		} while ((all_ana_cal_status == 0) && (cnt != 0));
++
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
++	}
++
++	if(all_ana_cal_status == 0){
++		pr_info("!!!!!!!!!!!! dev1Eh_reg17b ERROR\n");
++	}
++
++	return all_ana_cal_status;
++}
++
++
++
++
++static int ge_cal_rext(struct dsa_switch *ds, u8 phyaddr, u32 delay)
++{
++	u8 rg_zcal_ctrl, all_ana_cal_status;
++	u16 ad_cal_comp_out_init;
++	u16 dev1e_e0_ana_cal_r5;
++	int calibration_polarity;
++	u8 cnt = 0;
++	u16 dev1e_17a_tmp, dev1e_e0_tmp;
++
++	/* *** Iext/Rext Cal start ************ */
++	all_ana_cal_status = ANACAL_INIT;
++	/* analog calibration enable, Rext calibration enable */
++	/* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */
++	/* 1e_dc[0]:rg_txvos_calen */
++	/* 1e_e1[4]:rg_cal_refsel(0:1.2V) */
++	//tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00db, 0x1110)
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x1110);
++	//tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00dc, 0x0000);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0);
++	//tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00e1, 0x0000);
++	//tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x10);
++
++	rg_zcal_ctrl = 0x20;/* start with 0 dB */
++	dev1e_e0_ana_cal_r5 = tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0xe0); // get default value
++	/* 1e_e0[5:0]:rg_zcal_ctrl */
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0xe0, rg_zcal_ctrl);
++	all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr);/* delay 20 usec */
++
++	if (all_ana_cal_status == 0) {
++		all_ana_cal_status = ANACAL_ERROR;
++		printk(" GE Rext AnaCal ERROR init!   \r\n");
++		return -1;
++	}
++	/* 1e_17a[8]:ad_cal_comp_out */
++	ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x017a) >> 8) & 0x1;
++	if (ad_cal_comp_out_init == 1)
++		calibration_polarity = -1;
++	else /* ad_cal_comp_out_init == 0 */
++		calibration_polarity = 1;
++	cnt = 0;
++	while (all_ana_cal_status < ANACAL_ERROR) {
++		cnt++;
++		rg_zcal_ctrl += calibration_polarity;
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0xe0, (rg_zcal_ctrl));
++		all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); /* delay 20 usec */
++		dev1e_17a_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a);
++		if (all_ana_cal_status == 0) {
++			all_ana_cal_status = ANACAL_ERROR;
++			printk("  GE Rext AnaCal ERROR 2!   \r\n");
++			return -1;
++		} else if (((dev1e_17a_tmp >> 8) & 0x1) != ad_cal_comp_out_init) {
++			all_ana_cal_status = ANACAL_FINISH;
++			//printk("  GE Rext AnaCal Done! (%d)(0x%x)  \r\n", cnt, rg_zcal_ctrl);
++		} else {
++			dev1e_17a_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a);
++			dev1e_e0_tmp =	tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0xe0);
++			if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) {
++				all_ana_cal_status = ANACAL_SATURATION;  /* need to FT(IC fail?) */
++				printk(" GE Rext AnaCal Saturation!  \r\n");
++				rg_zcal_ctrl = 0x20;  /* 0 dB */
++			}
++		}
++	}
++
++	if (all_ana_cal_status == ANACAL_ERROR) {
++		rg_zcal_ctrl = 0x20;  /* 0 dB */
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
++	} else if(all_ana_cal_status == ANACAL_FINISH){
++		//tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, ((rg_zcal_ctrl << 8) | rg_zcal_ctrl));
++		printk("0x1e-e0 = %x\n", tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x00e0));
++		/* ****  1f_115[2:0] = rg_zcal_ctrl[5:3]  // Mog review */
++		tc_phy_write_dev_reg(ds, PHY0, 0x1f, 0x0115, ((rg_zcal_ctrl & 0x3f) >> 3));
++		printk("0x1f-115 = %x\n", tc_phy_read_dev_reg(ds,  PHY0, 0x1f, 0x115));
++		printk("  GE Rext AnaCal Done! (%d)(0x%x)  \r\n", cnt, rg_zcal_ctrl);
++		ge_cal_flag = 1;
++	} else {
++		printk("GE Rxet cal something wrong2\n");
++	}
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
++
++	return 0;
++}
++
++//-----------------------------------------------------------------
++static int ge_cal_r50(struct dsa_switch *ds, u8 phyaddr, u32 delay)
++{
++	u8 rg_zcal_ctrl, all_ana_cal_status, calibration_pair;
++	u16 ad_cal_comp_out_init;
++	u16 dev1e_e0_ana_cal_r5;
++	int calibration_polarity;
++	u8 cnt = 0;
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x1100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);	// 1e_dc[0]:rg_txvos_calen
++
++	for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) {
++		rg_zcal_ctrl = 0x20;  						// start with 0 dB
++		dev1e_e0_ana_cal_r5 = (tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x00e0) & (~0x003f));
++		tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));	// 1e_e0[5:0]:rg_zcal_ctrl
++		if(calibration_pair == ANACAL_PAIR_A)
++		{
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x1101);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
++			//printk("R50 pair A 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00dc));
++
++		}
++		else if(calibration_pair == ANACAL_PAIR_B)
++		{
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x1100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x1000);	// 1e_dc[12]:rg_zcalen_b
++			//printk("R50 pair B 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00db),tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00dc));
++
++		}
++		else if(calibration_pair == ANACAL_PAIR_C)
++		{
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x1100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0100);	// 1e_dc[8]:rg_zcalen_c
++			//printk("R50 pair C 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00dc));
++
++		}
++		else // if(calibration_pair == ANACAL_PAIR_D)
++		{
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x1100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0010);	// 1e_dc[4]:rg_zcalen_d
++			//printk("R50 pair D 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x00dc));
++
++		}
++
++		all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
++		if(all_ana_cal_status == 0)
++		{
++			all_ana_cal_status = ANACAL_ERROR;
++			printk( "GE R50 AnaCal ERROR init!   \r\n");
++			return -1;
++		}
++
++		ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x017a)>>8) & 0x1;		// 1e_17a[8]:ad_cal_comp_out
++		if(ad_cal_comp_out_init == 1)
++			calibration_polarity = -1;
++		else
++			calibration_polarity = 1;
++
++		cnt = 0;
++		while(all_ana_cal_status < ANACAL_ERROR)
++		{
++			cnt ++;
++			rg_zcal_ctrl += calibration_polarity;
++			tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
++			all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
++
++			if(all_ana_cal_status == 0)
++			{
++				all_ana_cal_status = ANACAL_ERROR;
++				printk( "  GE R50 AnaCal ERROR 2!   \r\n");
++				return -1;
++			}
++			else if(((tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init)
++			{
++				all_ana_cal_status = ANACAL_FINISH;
++			}
++			else {
++				if((rg_zcal_ctrl == 0x3F)||(rg_zcal_ctrl == 0x00))
++				{
++					all_ana_cal_status = ANACAL_SATURATION;  // need to FT
++					printk( " GE R50 AnaCal Saturation!  \r\n");
++				}
++			}
++		}
++
++		if(all_ana_cal_status == ANACAL_ERROR) {
++			rg_zcal_ctrl = 0x20;  // 0 dB
++			//tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
++		}
++		else {
++			rg_zcal_ctrl = MT753x_ZCAL_TO_R50ohm_GE_TBL_100[rg_zcal_ctrl - 9];	// wait Mog zcal/r50 mapping table
++			printk( " GE R50 AnaCal Done! (%d) (0x%x)(0x%x) \r\n", cnt, rg_zcal_ctrl, (rg_zcal_ctrl|0x80));
++		}
++
++		if(calibration_pair == ANACAL_PAIR_A) {
++			ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174) & (~0x7f00);
++			//ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174);
++			//printk( " GE-a 1e_174(0x%x)(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), ad_cal_comp_out_init, tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000)));	// 1e_174[15:8]
++			//printk( " GE-a 1e_174(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++		}
++		else if(calibration_pair == ANACAL_PAIR_B) {
++			ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174) & (~0x007f);
++			//ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174);
++			//printk( " GE-b 1e_174(0x%x)(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), ad_cal_comp_out_init, tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080)));	// 1e_174[7:0]
++			//printk( " GE-b 1e_174(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++		}
++		else if(calibration_pair == ANACAL_PAIR_C) {
++			ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175) & (~0x7f00);
++			//ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175);
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000)));	// 1e_175[15:8]
++			//printk( " GE-c 1e_174(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++		} else {// if(calibration_pair == ANACAL_PAIR_D)
++			ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175) & (~0x007f);
++			//ad_cal_comp_out_init = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175);
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080)));	// 1e_175[7:0]
++			//printk( " GE-d 1e_174(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++		}
++		//tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00e0, ((rg_zcal_ctrl<<8)|rg_zcal_ctrl));
++	}
++
++	printk( " GE 1e_174(0x%x), 1e_175(0x%x)  \r\n", tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x0175));
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
++
++	return 0;
++}
++
++static int ge_cal_tx_offset(struct dsa_switch *ds,  u8 phyaddr, u32 delay)
++{
++	u8 all_ana_cal_status, calibration_pair;
++	u16 ad_cal_comp_out_init;
++	int calibration_polarity, tx_offset_temp;
++	u8 tx_offset_reg_shift, tabl_idx, i;
++	u8 cnt = 0;
++	u16 tx_offset_reg, reg_temp, cal_temp;
++	//switch_phy_write(phyaddr, R0, 0x2100);//harry tmp
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0001);	// 1e_dc[0]:rg_txvos_calen
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0096, 0x8000);	// 1e_96[15]:bypass_tx_offset_cal, Hw bypass, Fw cal
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0xf808);	// 1e_3e
++	for(i = 0; i <= 4; i++)
++		tc_phy_write_dev_reg(ds, i, 0x1e, 0x00dd, 0x0000);
++	for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++)
++	{
++		tabl_idx = 31;
++		tx_offset_temp = MT753x_TX_OFFSET_TBL[tabl_idx];
++
++		if(calibration_pair == ANACAL_PAIR_A) {
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, 0x145, 0x5010);
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x1000);				// 1e_dd[12]:rg_txg_calen_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_0V));	// 1e_17d:dac_in0_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_0V));	// 1e_181:dac_in1_a
++			//printk("tx offset pairA 1e_dd = %x, 1e_17d=%x, 1e_181=%x\n", tc_phy_read_dev_reg(phyaddr, 0x1e, 0x00dd), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x017d), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x0181));
++			reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0172) & (~0x3f00));
++			tx_offset_reg_shift = 8;									// 1e_172[13:8]
++			tx_offset_reg = 0x0172;
++
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
++		} else if(calibration_pair == ANACAL_PAIR_B) {
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, 0x145, 0x5018);
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0100);				// 1e_dd[8]:rg_txg_calen_b
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_0V));	// 1e_17e:dac_in0_b
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_0V));	// 1e_182:dac_in1_b
++			//printk("tx offset pairB 1e_dd = %x, 1e_17d=%x, 1e_181=%x\n", tc_phy_read_dev_reg(phyaddr, 0x1e, 0x00dd), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x017d), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x0181));
++			reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0172) & (~0x003f));
++			tx_offset_reg_shift = 0;									// 1e_172[5:0]
++			tx_offset_reg = 0x0172;
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
++		} else if(calibration_pair == ANACAL_PAIR_C) {
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0010);				// 1e_dd[4]:rg_txg_calen_c
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_0V));	// 1e_17f:dac_in0_c
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_0V));	// 1e_183:dac_in1_c
++			reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0173) & (~0x3f00));
++			//printk("tx offset pairC 1e_dd = %x, 1e_17d=%x, 1e_181=%x\n", tc_phy_read_dev_reg(phyaddr, 0x1e, 0x00dd), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x017d), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x0181));
++			tx_offset_reg_shift = 8;									// 1e_173[13:8]
++			tx_offset_reg = 0x0173;
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
++		} else {// if(calibration_pair == ANACAL_PAIR_D)
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0001);				// 1e_dd[0]:rg_txg_calen_d
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_0V));	// 1e_180:dac_in0_d
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_0V));	// 1e_184:dac_in1_d
++			//printk("tx offset pairD 1e_dd = %x, 1e_17d=%x, 1e_181=%x\n", tc_phy_read_dev_reg(phyaddr, 0x1e, 0x00dd), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x017d), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x0181));
++			reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0173) & (~0x003f));
++			tx_offset_reg_shift = 0;									// 1e_173[5:0]
++			tx_offset_reg = 0x0173;
++			//tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
++		}
++		tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));	// 1e_172, 1e_173
++		all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
++		if(all_ana_cal_status == 0) {
++			all_ana_cal_status = ANACAL_ERROR;
++			printk( " GE Tx offset AnaCal ERROR init!   \r\n");
++			return -1;
++		}
++
++		ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8) & 0x1;		// 1e_17a[8]:ad_cal_comp_out
++		if(ad_cal_comp_out_init == 1)
++			calibration_polarity = 1;
++		else
++			calibration_polarity = -1;
++
++		cnt = 0;
++		//printk("TX offset cnt = %d, tabl_idx= %x, offset_val = %x\n", cnt, tabl_idx, MT753x_TX_OFFSET_TBL[tabl_idx]);
++		while(all_ana_cal_status < ANACAL_ERROR) {
++
++			cnt ++;
++			tabl_idx += calibration_polarity;
++			//tx_offset_temp += calibration_polarity;
++			//cal_temp = tx_offset_temp;
++			cal_temp = MT753x_TX_OFFSET_TBL[tabl_idx];
++			//printk("TX offset cnt = %d, tabl_idx= %x, offset_val = %x\n", cnt, tabl_idx, MT753x_TX_OFFSET_TBL[tabl_idx]);
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(cal_temp<<tx_offset_reg_shift)));
++
++			all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
++			if(all_ana_cal_status == 0) {
++				all_ana_cal_status = ANACAL_ERROR;
++				printk( " GE Tx offset AnaCal ERROR init 2!   \r\n");
++				return -1;
++			} else if(((tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init) {
++				all_ana_cal_status = ANACAL_FINISH;
++			} else {
++				if((tabl_idx == 0)||(tabl_idx == 0x3f)) {
++					all_ana_cal_status = ANACAL_SATURATION;  // need to FT
++					printk( " GE Tx offset AnaCal Saturation!  \r\n");
++				}
++			}
++		}
++
++		if(all_ana_cal_status == ANACAL_ERROR) {
++			tx_offset_temp = TX_AMP_OFFSET_0MV;
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
++		} else {
++			printk( " GE Tx offset AnaCal Done! (pair-%d)(%d)(0x%x) 0x1e_%x=0x%x\n", calibration_pair, cnt, MT753x_TX_OFFSET_TBL[tabl_idx], tx_offset_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg));
++		}
++	}
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, 0x0000);
++
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);	// disable analog calibration circuit
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);	// disable Tx offset calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);	// disable analog calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);	// disable Tx offset calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0x0000);	// disable Tx VLD force mode
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0000);	// disable Tx offset/amplitude calibration circuit
++
++	return 0;
++}
++
++u16 tx_amp_check_thres(int pair, u32 reg, u16 val, s16 offset)
++{
++	if ((offset < 0 && (0 - offset) > TX_AMP_MAX_OFFSET) ||
++	    (offset > TX_AMP_MAX_OFFSET)) {
++		pr_info(" offset=%d exceed tx amp max offset=%d\n", offset, TX_AMP_MAX_OFFSET);
++		return val;
++	}
++
++	if (offset < 0 && val < TX_AMP_LOW_TS - offset) {
++		if (val < TX_AMP_LOWEST_TS - offset) {
++			pr_info(" GE Tx amp AnaCal underflow! (pair-%d)(1e_%x) seed 0x%x < 0x%x)\n",
++				pair, reg, val, TX_AMP_LOWEST_TS - offset);
++		}
++		return 0;
++	}
++
++	if (offset >= 0 && val > TX_AMP_HIGH_TS - offset) {
++		if ( val > TX_AMP_HIGHEST_TS - offset) {
++			pr_info(" GE Tx amp AnaCal overflow! (pair-%d)(1e_%x) seed = 0x%x > 0x%x)\n",
++				pair, reg, val, TX_AMP_HIGHEST_TS - offset);
++		}
++		return TX_AMP_MAX;
++	}
++
++	return val + offset;
++}
++
++static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
++{
++	u8	all_ana_cal_status, calibration_pair, i;
++	u16	ad_cal_comp_out_init;
++	int	calibration_polarity;
++	u32	tx_amp_reg_shift;
++	u16	reg_temp;
++	u32	tx_amp_temp, tx_amp_reg, cnt=0, tx_amp_reg_100;
++	u32	debug_tmp, reg_backup, reg_tmp;
++	u32	orig_1e_11, orig_1f_300;
++
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x1100);	// 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0001);	// 1e_dc[0]:rg_txvos_calen
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x0010);	// 1e_e1[4]:select 1V
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0xf808);	// 1e_3e:enable Tx VLD
++
++	orig_1e_11 = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x11);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, 0xff00);
++//	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27a, 0x33);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0xc9, 0xffff);
++	orig_1f_300 = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x300);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x300, 0x4);
++	for(i = 0; i <= 4; i++)
++		tc_phy_write_dev_reg(ds, i, 0x1e, 0x00dd, 0x0000);
++	for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) {
++		tx_amp_temp = 0x20;	// start with 0 dB
++
++		if(calibration_pair == ANACAL_PAIR_A) {
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x1000);				// 1e_dd[12]:tx_a amp calibration enable
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_2V));	// 1e_17d:dac_in0_a
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_2V));	// 1e_181:dac_in1_a
++			reg_temp = (tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x012) & (~0xfc00));
++			tx_amp_reg_shift = 10;										// 1e_12[15:10]
++			tx_amp_reg = 0x12;
++			tx_amp_reg_100 = 0x16;
++		} else if(calibration_pair == ANACAL_PAIR_B) {
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0100);				// 1e_dd[8]:tx_b amp calibration enable
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_2V));	// 1e_17e:dac_in0_b
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_2V));	// 1e_182:dac_in1_b
++			reg_temp = (tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x017) & (~0x3f00));
++			tx_amp_reg_shift = 8;										// 1e_17[13:8]
++			tx_amp_reg = 0x17;
++			tx_amp_reg_100 = 0x18;
++		} else if(calibration_pair == ANACAL_PAIR_C) {
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0010);				// 1e_dd[4]:tx_c amp calibration enable
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_2V));	// 1e_17f:dac_in0_c
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_2V));	// 1e_183:dac_in1_c
++			reg_temp = (tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x019) & (~0x3f00));
++			tx_amp_reg_shift = 8;										// 1e_19[13:8]
++			tx_amp_reg = 0x19;
++			tx_amp_reg_100 = 0x20;
++		} else { //if(calibration_pair == ANACAL_PAIR_D)
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0001);				// 1e_dd[0]:tx_d amp calibration enable
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_2V));	// 1e_180:dac_in0_d
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_2V));	// 1e_184:dac_in1_d
++			reg_temp = (tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x021) & (~0x3f00));
++			tx_amp_reg_shift = 8;										// 1e_21[13:8]
++			tx_amp_reg = 0x21;
++			tx_amp_reg_100 = 0x22;
++		}
++		tc_phy_write_dev_reg( ds, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));	// 1e_12, 1e_17, 1e_19, 1e_21
++		tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
++		all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); 	// delay 20 usec
++		if(all_ana_cal_status == 0) {
++			all_ana_cal_status = ANACAL_ERROR;
++			printk( " GE Tx amp AnaCal ERROR init init!   \r\n");
++			return -1;
++		}
++
++		ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x017a)>>8) & 0x1;		// 1e_17a[8]:ad_cal_comp_out
++		if(ad_cal_comp_out_init == 1)
++			calibration_polarity = -1;
++		else
++			calibration_polarity = 1;
++
++		cnt =0;
++		while(all_ana_cal_status < ANACAL_ERROR) {
++			cnt ++;
++			tx_amp_temp += calibration_polarity;
++			//printk("tx_amp : %x, 1e %x = %x\n", tx_amp_temp, tx_amp_reg, (reg_temp|(tx_amp_temp<<tx_amp_reg_shift)));
++			tc_phy_write_dev_reg( ds, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
++			all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
++			if(all_ana_cal_status == 0) {
++				all_ana_cal_status = ANACAL_ERROR;
++				printk( " GE Tx amp AnaCal ERROR 2!   \r\n");
++				return -1;
++			} else if(((tc_phy_read_dev_reg(ds,  PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init) {
++				//printk("TX AMP ANACAL_FINISH\n");
++				all_ana_cal_status = ANACAL_FINISH;
++				if (phyaddr == 0) {
++					if (calibration_pair == ANACAL_PAIR_A)
++						tx_amp_temp = tx_amp_temp - 2;
++					else if(calibration_pair == ANACAL_PAIR_B)
++						tx_amp_temp = tx_amp_temp - 1;
++					else if(calibration_pair == ANACAL_PAIR_C)
++						tx_amp_temp = tx_amp_temp - 2;
++					else if(calibration_pair == ANACAL_PAIR_D)
++						tx_amp_temp = tx_amp_temp - 1;
++				} else if (phyaddr == 1) {
++					if (calibration_pair == ANACAL_PAIR_A)
++						tx_amp_temp = tx_amp_temp - 1;
++					else if(calibration_pair == ANACAL_PAIR_B)
++						tx_amp_temp = tx_amp_temp ;
++					else if(calibration_pair == ANACAL_PAIR_C)
++						tx_amp_temp = tx_amp_temp - 1;
++					else if(calibration_pair == ANACAL_PAIR_D)
++						tx_amp_temp = tx_amp_temp - 1;
++				} else if (phyaddr == 2) {
++					if (calibration_pair == ANACAL_PAIR_A)
++						tx_amp_temp = tx_amp_temp;
++					else if(calibration_pair == ANACAL_PAIR_B)
++						tx_amp_temp = tx_amp_temp - 1;
++					else if(calibration_pair == ANACAL_PAIR_C)
++						tx_amp_temp = tx_amp_temp;
++					else if(calibration_pair == ANACAL_PAIR_D)
++						tx_amp_temp = tx_amp_temp - 1;
++				} else if (phyaddr == 3) {
++					tx_amp_temp = tx_amp_temp;
++				} else if (phyaddr == 4) {
++					if (calibration_pair == ANACAL_PAIR_A)
++						tx_amp_temp = tx_amp_temp;
++					else if(calibration_pair == ANACAL_PAIR_B)
++						tx_amp_temp = tx_amp_temp - 1;
++					else if(calibration_pair == ANACAL_PAIR_C)
++						tx_amp_temp = tx_amp_temp;
++					else if(calibration_pair == ANACAL_PAIR_D)
++						tx_amp_temp = tx_amp_temp;
++				}
++				reg_temp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, tx_amp_reg)&(~0xff00);
++				tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
++				tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
++				if (phyaddr == 0) {
++					if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg_100 == 0x16) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 1+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++					if (tx_amp_reg_100 == 0x18) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++				} else if (phyaddr == 1) {
++					if (tx_amp_reg == 0x12) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 9);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg == 0x17){
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg_100 == 0x16) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++					if (tx_amp_reg_100 == 0x18) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++				} else if (phyaddr == 2) {
++					if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 6);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if ((tx_amp_reg_100 == 0x16) || (tx_amp_reg_100 == 0x18)) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++				} else if (phyaddr == 3) {
++					if (tx_amp_reg == 0x12) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg == 0x17) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg_100 == 0x16) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -2+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++					if (tx_amp_reg_100 == 0x18) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+3);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++				} else if (phyaddr == 4) {
++					if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 5);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
++					}
++					if (tx_amp_reg_100 == 0x16) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -2+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
++					if (tx_amp_reg_100 == 0x18) {
++						//printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++						reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
++						tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
++						//printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg_100, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100));
++					}
+				}
++
++				if (calibration_pair == ANACAL_PAIR_A){
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x12);
++					reg_tmp = ((reg_backup & 0xfc00) >> 10);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = 0x0000;
++					reg_backup |= ((tx_amp_temp << 10) | (tx_amp_temp << 0));
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x12, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x12);
++					//printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x16);
++					reg_tmp = ((reg_backup & 0x3f) >> 0);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f));
++					reg_backup |= (tx_amp_temp << 0);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x16, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x16);
++					//printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup);
++				}
++				else if(calibration_pair == ANACAL_PAIR_B){
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x17);
++					reg_tmp = ((reg_backup & 0x3f00) >> 8);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = 0x0000;
++                                       reg_backup |= ((tx_amp_temp << 8) | (tx_amp_temp << 0));
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x17, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x17);
++					//printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x18);
++					reg_tmp = ((reg_backup & 0x3f) >> 0);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f));
++					reg_backup |= (tx_amp_temp << 0);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x18);
++					//printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup);
++				}
++				else if(calibration_pair == ANACAL_PAIR_C){
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x19);
++					reg_tmp = ((reg_backup & 0x3f00) >> 8);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f00));
++					reg_backup |= (tx_amp_temp << 8);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x19, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x19);
++					//printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x20);
++					reg_tmp = ((reg_backup & 0x3f) >> 0);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f));
++					reg_backup |= (tx_amp_temp << 0);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x20, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x20);
++					//printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup);
++				}
++				else if(calibration_pair == ANACAL_PAIR_D){
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x21);
++					reg_tmp = ((reg_backup & 0x3f00) >> 8);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f00));
++					reg_backup |= (tx_amp_temp << 8);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x21, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x21);
++					//printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x22);
++					reg_tmp = ((reg_backup & 0x3f) >> 0);
++					tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
++					reg_backup = (reg_backup & (~0x3f));
++					reg_backup |= (tx_amp_temp << 0);
++					tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x22, reg_backup);
++					reg_backup = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x22);
++					//printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup);
++				}
++
++				if (calibration_pair == ANACAL_PAIR_A){
++					//printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x12);
++					//printk("1e.012 = 0x%x\n", debug_tmp);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x16);
++					//printk("1e.016 = 0x%x\n", debug_tmp);
++				}
++
++				else if(calibration_pair == ANACAL_PAIR_B){
++					//printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x17);
++					//printk("1e.017 = 0x%x\n", debug_tmp);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x18);
++					//printk("1e.018 = 0x%x\n", debug_tmp);
++				}
++				else if(calibration_pair == ANACAL_PAIR_C){
++					//printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x19);
++					//printk("1e.019 = 0x%x\n", debug_tmp);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x20);
++					//printk("1e.020 = 0x%x\n", debug_tmp);
++				}
++				else if(calibration_pair == ANACAL_PAIR_D){
++					//printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x21);
++					//printk("1e.021 = 0x%x\n", debug_tmp);
++					debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x22);
++					//printk("1e.022 = 0x%x\n", debug_tmp);
++				}
++
++
++				printk( " GE Tx amp AnaCal Done! (pair-%d)(1e_%x = 0x%x)(0x%x)\n", calibration_pair, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg), reg_tmp);
++
++			} else {
++				if((tx_amp_temp == 0x3f)||(tx_amp_temp == 0x00)) {
++					all_ana_cal_status = ANACAL_SATURATION;  // need to FT
++					printk( " GE Tx amp AnaCal Saturation!  \r\n");
++				}
++			}
++		}
++
++		if(all_ana_cal_status == ANACAL_ERROR) {
++			tx_amp_temp = 0x20;
++			tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, (reg_temp|(tx_amp_temp<<tx_amp_reg_shift)));
++		}
++	}
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, 0x0000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, 0x0000);
++
++	/* disable analog calibration circuit */
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);	// disable Tx offset calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);	// disable analog calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);	// disable Tx offset calibration circuit
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0x0000);	// disable Tx VLD force mode
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0000);	// disable Tx offset/amplitude calibration circuit
++
++
++
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x2000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0xc9, 0x0fff);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x145, 0x1000);
++
++	/* Restore CR to default */
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, orig_1e_11);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x300, orig_1f_300);
++
++	return 0;
++}
++
++//-----------------------------------------------------------------
++
++static int phy_calibration(struct dsa_switch *ds, u8 phyaddr)
++{
++	//u32	reg_tmp,reg_tmp0, reg_tmp1, i;
++	u32 reg_tmp;
++	u32 CALDLY = 40;
++	u32 orig_1e_11, orig_1e_185, orig_1e_e1, orig_1f_100;
++	int ret;
++
++	/* Use SW calibration data. */
++	reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x403);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x403, reg_tmp | BIT(3));
++	/* set [12]AN disable, [8]full duplex, [13/6]1000Mbps */
++	//tc_phy_write_dev_reg(phyaddr, 0x0,  0x0140);
++	switch_phy_write(ds, phyaddr, R0, 0x140);
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x145, 0x1010);/* fix mdi */
++	orig_1e_185 = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, RG_185);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, RG_185, 0);/* disable tx slew control */
++	orig_1f_100 = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x100);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x100, 0xc000);/* BG voltage output */
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x403, 0x1099); //bypass efuse
++
++#if (1)
++	//	1f_27c[12:8] cr_da_tx_i2mpb_10m	Trimming TX bias setup(@10M)
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x1f1f);
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x3300);
++
++	//reg_tmp1 = tc_phy_read_dev_reg(ds,  PHY0, 0x1f, 0x27c);
++	//dev1Fh_reg273h TXVLD DA register	- Adjust voltage mode TX amplitude.
++	//tc_phy_write_dev_reg(phyaddr, 0x1f, 0x273, 0);
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x1000);
++	//reg_tmp1 = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x273);
++	//printk("reg_tmp1273 = %x\n", reg_tmp1);
++	/*1e_11 TX  overshoot Enable (PAIR A/B/C/D) in gbe mode*/
++
++	orig_1e_11 = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x11);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x11);
++	reg_tmp = reg_tmp | (0xf << 12);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, reg_tmp);
++	orig_1e_e1 = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x00e1);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x10);
++	/* calibration start ============ */
++	printk("CALDLY = %d\n", CALDLY);
++	if(ge_cal_flag == 0){
++		ret = ge_cal_rext(ds, 0, CALDLY);
++		if (ret == -1){
++			printk("ge_cal_rext error K port =%d\n", phyaddr);
++			return ret;
++		}
++		ge_cal_flag = 1;
++	}
++
++	/* *** R50 Cal start ***************************** */
++	/*phyaddress = 0*/
++	ret = ge_cal_r50(ds, phyaddr, CALDLY);
++	if (ret == -1){
++		printk("R50 error K port =%d\n", phyaddr);
++		return ret;
++	}
++	/* *** R50 Cal end *** */
++	/* *** Tx offset Cal start *********************** */
++	ret = ge_cal_tx_offset(ds, phyaddr, CALDLY);
++	if (ret == -1){
++		printk("ge_cal_tx_offset error K port =%d\n", phyaddr);
++		return ret;
++	}
++	/* *** Tx offset Cal end *** */
++
++	/* *** Tx Amp Cal start *** */
++	ret = ge_cal_tx_amp(ds, phyaddr, CALDLY);
++	if (ret == -1){
++		printk("ge_cal_tx_amp error K port =%d\n", phyaddr);
++		return ret;
++	}
++	/* *** Tx Amp Cal end *** */
++	/*tmp maybe changed*/
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x1111);
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27b, 0x47);
++	//tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x2000);
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3a8, 0x0810);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3aa, 0x0008);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ab, 0x0810);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ad, 0x0008);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ae, 0x0106);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b0, 0x0001);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b1, 0x0106);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b3, 0x0001);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18c, 0x0001);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18d, 0x0001);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18e, 0x0001);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18f, 0x0001);
++
++	/*da_tx_bias1_b_tx_standby = 5'b10 (dev1eh_reg3aah[12:8])*/
++	reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x3aa);
++	reg_tmp = reg_tmp & ~(0x1f00);
++	reg_tmp = reg_tmp | 0x2 << 8;
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3aa, reg_tmp);
++
++	/*da_tx_bias1_a_tx_standby = 5'b10 (dev1eh_reg3a9h[4:0])*/
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1e, 0x3a9);
++	reg_tmp = reg_tmp & ~(0x1f);
++	reg_tmp = reg_tmp | 0x2;
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3a9, reg_tmp);
++
++	/* Restore CR to default */
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, RG_185, orig_1e_185);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x100, orig_1f_100);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, orig_1e_11);
++	tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, orig_1e_e1);
++#endif
++	return 0;
++}
++
++static void rx_dc_offset(struct dsa_switch *ds, u8 phyaddr)
++{
++	pr_info("PORT %d RX_DC_OFFSET\n", phyaddr);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x96, 0x8000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x37, 0x3);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x107, 0x4000);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x171, 0x1e5);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x39, 0x200f);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x39, 0x000f);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x171, 0x65);
++}
++
++static void check_rx_dc_offset_pair_a(struct dsa_switch *ds, u8 phyaddr)
++{
++	u32 reg_tmp;
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x114f);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("before pairA output = %x\n", reg_tmp);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1142);
++	udelay(40);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("after pairA output = %x\n", reg_tmp);
++	if ((reg_tmp & 0x80) != 0)
++		reg_tmp = (~reg_tmp) + 1;
++	if ((reg_tmp & 0xff) >4)
++		pr_info("pairA RX_DC_OFFSET error");
++}
++
++static void check_rx_dc_offset_pair_b(struct dsa_switch *ds, u8 phyaddr)
++{
++	u32 reg_tmp;
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1151);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("before pairB output = %x\n", reg_tmp);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1143);
++	udelay(40);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("after pairB output = %x\n", reg_tmp);
++	if ((reg_tmp & 0x80) != 0)
++		reg_tmp = (~reg_tmp) + 1;
++	if ((reg_tmp & 0xff) >4)
++		pr_info("pairB RX_DC_OFFSET error");
++}
++
++static void check_rx_dc_offset_pair_c(struct dsa_switch *ds, u8 phyaddr)
++{
++	u32 reg_tmp;
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1153);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("before pairC output = %x\n", reg_tmp);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1144);
++	udelay(40);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("after pairC output = %x\n", reg_tmp);
++	if ((reg_tmp & 0x80) != 0)
++		reg_tmp = (~reg_tmp) + 1;
++	if ((reg_tmp & 0xff) >4)
++		pr_info("pairC RX_DC_OFFSET error");
++}
++
++static void check_rx_dc_offset_pair_d(struct dsa_switch *ds, u8 phyaddr)
++{
++	u32 reg_tmp;
++
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1155);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("before pairD output = %x\n", reg_tmp);
++	udelay(40);
++	tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1145);
++	udelay(40);
++	reg_tmp = tc_phy_read_dev_reg(ds,  phyaddr, 0x1f, 0x1a);
++	reg_tmp = reg_tmp & 0xff;
++	pr_info("after pairD output = %x\n", reg_tmp);
++	if ((reg_tmp & 0x80) != 0)
++		reg_tmp = (~reg_tmp) + 1;
++	if ((reg_tmp & 0xff) >4)
++		pr_info("pairD RX_DC_OFFSET error");
++}
++
++/* 12 registers for TX_MLT3 waveform tuning.
++ *    012 345 678 9ab
++ *  1    __
++ *     _/  \_
++ *  0_/      \
++ *            \_    _/
++ * -1           \__/
++ */
++static void mt7531_phy_100m_eye_diag_setting(struct dsa_switch *ds, u32 port)
++{
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x0, 0x187);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x1, 0x1c9);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x2, 0x1c6);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x3, 0x182);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x4, 0x208);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x5, 0x205);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x6, 0x384);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x7, 0x3cb);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x8, 0x3c4);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x9, 0x30a);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0xa, 0x00b);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0xb, 0x002);
++}
++
++static void mt7531_phy_setting(struct dsa_switch *ds)
++{
++	int i;
++	u32 val;
++
++	for (i = 0; i < MT7531_NUM_PHYS; i++) {
++		mt7531_phy_100m_eye_diag_setting(ds, i);
++
++		/* Enable HW auto downshift */
++		switch_phy_write(ds, i, 0x1f, 0x1);
++		val = switch_phy_read(ds, i, PHY_EXT_REG_14);
++		val |= PHY_EN_DOWN_SHFIT;
++		switch_phy_write(ds, i, PHY_EXT_REG_14, val);
++
++		/* Decrease SlvDPSready time */
++		val = mt753x_tr_read(ds, i, PMA_CH, PMA_NOD, PMA_17);
++		val &= ~SLV_DSP_READY_TIME_M;
++		val |= 0xc << SLV_DSP_READY_TIME_S;
++		mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_17, val);
++
++		/* Enable Random Update Mechanism */
++		val = mt753x_tr_read(ds, i, PMA_CH, PMA_NOD, PMA_18);
++		val |= ENABLE_RANDOM_UPDATE_TRIGGER;
++		mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_18, val);
++
++		/* PHY link down power saving enable */
++		val = switch_phy_read(ds, i, PHY_EXT_REG_17);
++		val |= PHY_LINKDOWN_POWER_SAVING_EN;
++		switch_phy_write(ds, i, PHY_EXT_REG_17, val);
++
++		val = tc_phy_read_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_0C6);
++		val &= ~PHY_POWER_SAVING_M;
++		val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
++		tc_phy_write_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val);
++
++		/* Timing Recovery for GbE slave mode */
++		mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_01, 0x6fb90a);
++		mt753x_tr_write(ds, i, DSP_CH, DSP_NOD, DSP_06, 0x2ebaef);
++		val = tc_phy_read_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_234);
++		val |= TR_OPEN_LOOP_EN;
++		tc_phy_write_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_234, val);
++
++		/* Enable Asymmetric Pause Capability */
++		val = switch_phy_read(ds, i, MII_ADVERTISE);
++		val |= ADVERTISE_PAUSE_ASYM;
++		switch_phy_write(ds, i, MII_ADVERTISE, val);
++	}
++}
++
++static void mt7531_adjust_line_driving(struct dsa_switch *ds, u32 port)
++{
++	/* For ADC timing margin window for LDO calibration */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222);
++
++	/* Adjust AD sample timing */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444);
++
++	/* Adjust Line driver current for different mode */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5);
++
++	/* Adjust Line driver current for different mode */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b);
++
++	/* Adjust Line driver gain for 10BT from 1000BT calibration result */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_273, 0x3000);
++
++	/* Adjust RX Echo path filter */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2);
++
++	/* Adjust RX HVGA bias current */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333);
++
++	/* Adjust TX class AB driver 1 */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x384);
++
++	/* Adjust TX class AB driver 2 */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x1114);
++
++	/* Adjust DAC delay for TX Pairs */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404);
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404);
++
++	/* Adjust DAC digital delay for TX Delay */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0);
++
++	/* Adjust Line driver compensation cap for stability concern due to
++	 * increase current.
++	 */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_26A, 0x3333);
++}
++
++static void mt7531_eee_setting(struct dsa_switch *ds, u32 port)
++{
++	u32 val;
++
++	/* Disable EEE */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV07, PHY_DEV07_REG_03C, 0);
++
++	/* Disable generate signal to clear the scramble_lock when lpi mode */
++	val = tc_phy_read_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_189);
++	val &= ~DESCRAMBLER_CLEAR_EN;
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_189, val);
++
++	/* Roll back EEE Slave Mode */
++	tc_phy_write_dev_reg(ds, port, 0x1e, 0x2d1, 0);
++	mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_08, 0x1b);
++	mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_0f, 0);
++	mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_10, 0x5000);
++
++	/* Adjust 100_mse_threshold */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
++
++	/* Disable mcc */
++	tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
++}
++
++int mt7531_phy_setup(struct dsa_switch *ds)
++{
++	int ret;
++	int i;
++
++	mt7531_phy_setting(ds);
++
++	for (i = 0; i < MT7531_NUM_PHYS; i++) {
++		mt7531_adjust_line_driving(ds, i);
++		mt7531_eee_setting(ds, i);
++	}
++
++	/*for (i = 0; i < MT7531_NUM_PHYS; i++) {
++		ret = phy_calibration(ds, i);
++
++		rx_dc_offset(ds, i);
++		check_rx_dc_offset_pair_a(ds, i);
++		check_rx_dc_offset_pair_b(ds, i);
++		check_rx_dc_offset_pair_c(ds, i);
++		check_rx_dc_offset_pair_d(ds, i);
++
++		switch_phy_write(ds, i, 0, 0x1040);
++	}*/
++
++	return ret;
++}
+Index: linux-5.4.124/drivers/net/dsa/mt7531_phy.h
+===================================================================
+--- /dev/null
++++ linux-5.4.124/drivers/net/dsa/mt7531_phy.h
+@@ -0,0 +1,262 @@
++/* SPDX-License-Identifier:	GPL-2.0+ */
++/*
++ * Register definitions for MediaTek MT753x Gigabit switches
++ *
++ * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
++ *
++ * Author: Weijie Gao <weijie.gao@mediatek.com>
++ */
++
++#ifndef _MT753X_PHY_H_
++#define _MT753X_PHY_H_
++
++#include <linux/bitops.h>
++
++/*phy calibration use*/
++#define DEV_1E				0x1E
++/*global device 0x1f, always set P0*/
++#define DEV_1F				0x1F
++
++
++/************IEXT/REXT CAL***************/
++/* bits range: for example BITS(16,23) = 0xFF0000*/
++#define BITS(m, n)   (~(BIT(m) - 1) & ((BIT(n) - 1) | BIT(n)))
++#define ANACAL_INIT			0x01
++#define ANACAL_ERROR			0xFD
++#define ANACAL_SATURATION		0xFE
++#define	ANACAL_FINISH			0xFF
++#define ANACAL_PAIR_A			0
++#define ANACAL_PAIR_B			1
++#define ANACAL_PAIR_C			2
++#define ANACAL_PAIR_D			3
++#define DAC_IN_0V			0x00
++#define DAC_IN_2V			0xf0
++#define TX_AMP_OFFSET_0MV		0x20
++#define TX_AMP_OFFSET_VALID_BITS	6
++
++#define R0				0
++#define PHY0				0
++#define PHY1				1
++#define PHY2				2
++#define PHY3				3
++#define PHY4				4
++#define ANA_TEST_MODE			BITS(8, 15)
++#define TST_TCLK_SEL			BITs(6, 7)
++#define ANA_TEST_VGA_RG			0x100
++
++#define FORCE_MDI_CROSS_OVER		BITS(3, 4)
++#define T10_TEST_CTL_RG			0x145
++#define RG_185				0x185
++#define RG_TX_SLEW			BIT(0)
++#define ANA_CAL_0			0xdb
++#define RG_CAL_CKINV			BIT(12)
++#define RG_ANA_CALEN			BIT(8)
++#define RG_REXT_CALEN			BIT(4)
++#define RG_ZCALEN_A			BIT(0)
++#define ANA_CAL_1			0xdc
++#define RG_ZCALEN_B			BIT(12)
++#define RG_ZCALEN_C			BIT(8)
++#define RG_ZCALEN_D			BIT(4)
++#define RG_TXVOS_CALEN			BIT(0)
++#define ANA_CAL_6			0xe1
++#define RG_CAL_REFSEL			BIT(4)
++#define RG_CAL_COMP_PWD			BIT(0)
++#define ANA_CAL_5			0xe0
++#define RG_REXT_TRIM			BITs(8, 13)
++#define RG_ZCAL_CTRL			BITs(0, 5)
++#define RG_17A				0x17a
++#define AD_CAL_COMP_OUT			BIT(8)
++#define RG_17B				0x17b
++#define AD_CAL_CLK			bit(0)
++#define RG_17C				0x17c
++#define DA_CALIN_FLAG			bit(0)
++/************R50 CAL****************************/
++#define RG_174				0x174
++#define RG_R50OHM_RSEL_TX_A_EN		BIT[15]
++#define CR_R50OHM_RSEL_TX_A		BITS[8:14]
++#define RG_R50OHM_RSEL_TX_B_EN		BIT[7]
++#define CR_R50OHM_RSEL_TX_B		BITS[6:0]
++#define RG_175				0x175
++#define RG_R50OHM_RSEL_TX_C_EN		BITS[15]
++#define CR_R50OHM_RSEL_TX_C		BITS[8:14]
++#define RG_R50OHM_RSEL_TX_D_EN		BIT[7]
++#define CR_R50OHM_RSEL_TX_D		BITS[0:6]
++/**********TX offset Calibration***************************/
++#define RG_95				0x96
++#define BYPASS_TX_OFFSET_CAL		BIT(15)
++#define RG_3E				0x3e
++#define BYPASS_PD_TXVLD_A		BIT(15)
++#define BYPASS_PD_TXVLD_B		BIT(14)
++#define BYPASS_PD_TXVLD_C		BIT(13)
++#define BYPASS_PD_TXVLD_D		BIT(12)
++#define BYPASS_PD_TX_10M		BIT(11)
++#define POWER_DOWN_TXVLD_A		BIT(7)
++#define POWER_DOWN_TXVLD_B		BIT(6)
++#define POWER_DOWN_TXVLD_C		BIT(5)
++#define POWER_DOWN_TXVLD_D		BIT(4)
++#define POWER_DOWN_TX_10M		BIT(3)
++#define RG_DD				0xdd
++#define RG_TXG_CALEN_A			BIT(12)
++#define RG_TXG_CALEN_B			BIT(8)
++#define RG_TXG_CALEN_C			BIT(4)
++#define RG_TXG_CALEN_D			BIT(0)
++#define RG_17D				0x17D
++#define FORCE_DASN_DAC_IN0_A		BIT(15)
++#define DASN_DAC_IN0_A			BITS(0, 9)
++#define RG_17E				0x17E
++#define FORCE_DASN_DAC_IN0_B		BIT(15)
++#define DASN_DAC_IN0_B			BITS(0, 9)
++#define RG_17F				0x17F
++
++#define FORCE_DASN_DAC_IN0_C		BIT(15)
++#define DASN_DAC_IN0_C			BITS(0, 9)
++#define RG_180				0x180
++#define FORCE_DASN_DAC_IN0_D		BIT(15)
++#define DASN_DAC_IN0_D			BITS(0, 9)
++
++#define RG_181				0x181
++#define FORCE_DASN_DAC_IN1_A		BIT(15)
++#define DASN_DAC_IN1_A			BITS(0, 9)
++#define RG_182				0x182
++#define FORCE_DASN_DAC_IN1_B		BIT(15)
++#define DASN_DAC_IN1_B			BITS(0, 9)
++#define RG_183				0x183
++#define FORCE_DASN_DAC_IN1_C		BIT(15)
++#define DASN_DAC_IN1_C			BITS(0, 9)
++#define RG_184				0x184
++#define FORCE_DASN_DAC_IN1_D		BIT(15)
++#define DASN_DAC_IN1_D			BITS(0, 9)
++#define RG_172				0x172
++#define CR_TX_AMP_OFFSET_A		BITS(8, 13)
++#define CR_TX_AMP_OFFSET_B		BITS(0, 5)
++#define RG_173				0x173
++#define CR_TX_AMP_OFFSET_C		BITS(8, 13)
++#define CR_TX_AMP_OFFSET_D		BITS(0, 5)
++/**********TX Amp Calibration ***************************/
++#define RG_12				0x12
++#define DA_TX_I2MPB_A_GBE		BITS(10, 15)
++#define RG_17				0x17
++#define DA_TX_I2MPB_B_GBE		BITS(8, 13)
++#define RG_19				0x19
++#define DA_TX_I2MPB_C_GBE		BITS(8, 13)
++#define RG_21				0x21
++#define DA_TX_I2MPB_D_GBE		BITS(8, 13)
++#define TX_AMP_MAX			0x3f
++#define TX_AMP_MAX_OFFSET		0xb
++#define TX_AMP_HIGHEST_TS		((TX_AMP_MAX) + 3)
++#define TX_AMP_LOWEST_TS		(0 - 3)
++#define TX_AMP_HIGH_TS			(TX_AMP_MAX)
++#define TX_AMP_LOW_TS			0
++
++/* PHY Extend Register 0x14 bitmap of define */
++#define PHY_EXT_REG_14			0x14
++
++/* Fields of PHY_EXT_REG_14 */
++#define PHY_EN_DOWN_SHFIT		BIT(4)
++
++/* PHY Extend Register 0x17 bitmap of define */
++#define PHY_EXT_REG_17			0x17
++
++/* Fields of PHY_EXT_REG_17 */
++#define PHY_LINKDOWN_POWER_SAVING_EN	BIT(4)
++
++/* PHY PMA Register 0x17 bitmap of define */
++#define SLV_DSP_READY_TIME_S		15
++#define SLV_DSP_READY_TIME_M		(0xff << SLV_DSP_READY_TIME_S)
++
++/* PHY PMA Register 0x18 bitmap of define */
++#define ENABLE_RANDOM_UPDATE_TRIGGER	BIT(8)
++
++/* PHY EEE Register bitmap of define */
++#define PHY_DEV07			0x07
++#define PHY_DEV07_REG_03C		0x3c
++
++/* PHY DEV 0x1e Register bitmap of define */
++#define PHY_DEV1E			0x1e
++#define PHY_DEV1F			0x1f
++
++/* Proprietory Control Register of Internal Phy device 0x1e */
++#define PHY_TX_MLT3_BASE		0x0
++#define PHY_DEV1E_REG_13		0x13
++#define PHY_DEV1E_REG_14		0x14
++#define PHY_DEV1E_REG_41		0x41
++#define PHY_DEV1E_REG_A6		0xa6
++#define RXADC_CONTROL_3			0xc2
++#define PHY_DEV1E_REG_0C6		0xc6
++#define RXADC_LDO_CONTROL_2		0xd3
++#define PHY_DEV1E_REG_0FE		0xfe
++#define PHY_DEV1E_REG_123		0x123
++#define PHY_DEV1E_REG_189		0x189
++#define PHY_DEV1E_REG_234		0x234
++
++/* Proprietory Control Register of Internal Phy device 0x1f */
++#define PHY_DEV1F_REG_44		0x44
++#define PHY_DEV1F_REG_268		0x268
++#define PHY_DEV1F_REG_269		0x269
++#define PHY_DEV1F_REG_26A		0x26A
++#define TXVLD_DA_271			0x271
++#define TXVLD_DA_272			0x272
++#define TXVLD_DA_273			0x273
++
++/* Fields of PHY_DEV1E_REG_0C6 */
++#define PHY_POWER_SAVING_S		8
++#define PHY_POWER_SAVING_M		0x300
++#define PHY_POWER_SAVING_TX		0x0
++
++/* Fields of PHY_DEV1E_REG_189 */
++#define DESCRAMBLER_CLEAR_EN		0x1
++
++/* Fields of PHY_DEV1E_REG_234 */
++#define TR_OPEN_LOOP_EN			BIT(0)
++
++/* Internal GPHY Page Control Register */
++#define PHY_CL22_PAGE_CTRL		0x1f
++#define PHY_TR_PAGE			0x52b5
++
++/* Internal GPHY Token Ring Access Registers */
++#define PHY_TR_CTRL			0x10
++#define PHY_TR_LOW_DATA			0x11
++#define PHY_TR_HIGH_DATA		0x12
++
++/* Fields of PHY_TR_CTRL */
++#define PHY_TR_PKT_XMT_STA		BIT(15)
++#define PHY_TR_WR_S			13
++#define PHY_TR_CH_ADDR_S		11
++#define PHY_TR_NODE_ADDR_S		7
++#define PHY_TR_DATA_ADDR_S		1
++
++enum phy_tr_wr {
++	PHY_TR_WRITE = 0,
++	PHY_TR_READ = 1,
++};
++
++/* Helper macro for GPHY Token Ring Access */
++#define PHY_TR_LOW_VAL(x)		((x) & 0xffff)
++#define PHY_TR_HIGH_VAL(x)		(((x) & 0xff0000) >> 16)
++
++/* Token Ring Channels */
++#define PMA_CH				0x1
++#define DSP_CH				0x2
++
++/* Token Ring Nodes */
++#define PMA_NOD				0xf
++#define DSP_NOD				0xd
++
++/* Token Ring register range */
++enum tr_pma_reg_addr {
++	PMA_MIN = 0x0,
++	PMA_01  = 0x1,
++	PMA_17  = 0x17,
++	PMA_18  = 0x18,
++	PMA_MAX = 0x3d,
++};
++
++enum tr_dsp_reg_addr {
++	DSP_MIN = 0x0,
++	DSP_06  = 0x6,
++	DSP_08  = 0x8,
++	DSP_0f  = 0xf,
++	DSP_10  = 0x10,
++	DSP_MAX = 0x3e,
++};
++#endif /* _MT753X_REGS_H_ */
+Index: linux-5.4.124/drivers/net/dsa/Makefile
+===================================================================
+--- linux-5.4.124.orig/drivers/net/dsa/Makefile
++++ linux-5.4.124/drivers/net/dsa/Makefile
+@@ -6,7 +6,8 @@ ifdef CONFIG_NET_DSA_LOOP
+ obj-$(CONFIG_FIXED_PHY)		+= dsa_loop_bdinfo.o
+ endif
+ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
+-obj-$(CONFIG_NET_DSA_MT7530)	+= mt7530.o
++obj-$(CONFIG_NET_DSA_MT7530)	+= mt7530-dsa.o
++mt7530-dsa-objs			:= mt7530.o mt7531_phy.o
+ obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
+ obj-$(CONFIG_NET_DSA_QCA8K)	+= qca8k.o
+ obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o