blob: bf4cef7b97adcbd78950155623418bb35535aef8 [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From b736c4488d00e4b6e363220746c666176c12ea90 Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:05:59 +0800
4Subject: [PATCH]
5 [backport-networking-drivers][999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch]
6
7---
8 drivers/net/dsa/Makefile | 3 +-
9 drivers/net/dsa/mt7530.c | 2 +
10 drivers/net/dsa/mt7530.h | 1 +
11 drivers/net/dsa/mt7531_phy.c | 1378 ++++++++++++++++++++++++++++++++++
12 drivers/net/dsa/mt7531_phy.h | 262 +++++++
13 5 files changed, 1645 insertions(+), 1 deletion(-)
14 create mode 100644 drivers/net/dsa/mt7531_phy.c
15 create mode 100644 drivers/net/dsa/mt7531_phy.h
16
17diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
18index ae70b7962..0aa10bc3d 100644
19--- a/drivers/net/dsa/Makefile
20+++ b/drivers/net/dsa/Makefile
21@@ -6,7 +6,8 @@ ifdef CONFIG_NET_DSA_LOOP
22 obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
23 endif
24 obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
25-obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
26+obj-$(CONFIG_NET_DSA_MT7530) += mt7530-dsa.o
27+mt7530-dsa-objs := mt7530.o mt7531_phy.o
28 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
29 obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
30 obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
31diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
32index 008432d5c..e4c021eeb 100644
33--- a/drivers/net/dsa/mt7530.c
34+++ b/drivers/net/dsa/mt7530.c
35@@ -1829,6 +1829,8 @@ mt7531_setup(struct dsa_switch *ds)
developer24091172021-07-06 16:36:48 +080036 PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
37 }
38
39+ mt7531_phy_setup(ds);
40+
41 /* Group and enable unused ports as a standalone dumb switch. */
42 setup_unused_ports(ds, unused_pm);
43
developer5d148cb2023-06-02 13:08:11 +080044diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
45index aa758b2d2..8f1e827ff 100644
46--- a/drivers/net/dsa/mt7530.h
47+++ b/drivers/net/dsa/mt7530.h
48@@ -782,4 +782,5 @@ static inline void INIT_MT7530_DUMMY_POLL(struct mt7530_dummy_poll *p,
developer24091172021-07-06 16:36:48 +080049 p->reg = reg;
50 }
51
52+int mt7531_phy_setup(struct dsa_switch *ds);
53 #endif /* __MT7530_H */
developer5d148cb2023-06-02 13:08:11 +080054diff --git a/drivers/net/dsa/mt7531_phy.c b/drivers/net/dsa/mt7531_phy.c
55new file mode 100644
56index 000000000..a5c1e7d54
developer24091172021-07-06 16:36:48 +080057--- /dev/null
developer5d148cb2023-06-02 13:08:11 +080058+++ b/drivers/net/dsa/mt7531_phy.c
developer24091172021-07-06 16:36:48 +080059@@ -0,0 +1,1378 @@
60+// SPDX-License-Identifier: GPL-2.0+
61+/*
62+ * Common part for MediaTek MT753x gigabit switch
63+ *
64+ * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
65+ *
66+ * Author: Weijie Gao <weijie.gao@mediatek.com>
67+ */
68+
69+#include <linux/delay.h>
70+#include <linux/hrtimer.h>
71+#include <linux/kernel.h>
72+#include <net/dsa.h>
73+#include "mt7530.h"
74+#include "mt7531_phy.h"
75+
76+#define MT7531_NUM_PHYS 5
77+
78+static u32 tc_phy_read_dev_reg(struct dsa_switch *ds, u32 port_num, u32 dev_addr, u32 reg_addr)
79+{
80+ struct mt7530_priv *priv = ds->priv;
81+ u32 phy_val;
82+ u32 addr;
83+
84+ addr = MII_ADDR_C45 | (dev_addr << 16) | (reg_addr & 0xffff);
85+ phy_val = priv->info->phy_read(ds, port_num, addr);
86+
87+ //printk("switch phy cl45 r %d 0x%x 0x%x = %x\n",port_num, dev_addr, reg_addr, phy_val);
88+ return phy_val;
89+}
90+
91+static void tc_phy_write_dev_reg(struct dsa_switch *ds, u32 port_num, u32 dev_addr, u32 reg_addr, u32 write_data)
92+{
93+ struct mt7530_priv *priv = ds->priv;
94+ u32 addr;
95+
96+ addr = MII_ADDR_C45 | (dev_addr << 16) | (reg_addr & 0xffff);
97+
98+ priv->info->phy_write(ds, port_num, addr, write_data);
99+
100+ //u32 phy_val = priv->info->phy_read(ds, port_num, addr);
101+ //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);
102+}
103+
104+static void switch_phy_write(struct dsa_switch *ds, u32 port_num, u32 reg_addr, u32 write_data){
105+ struct mt7530_priv *priv = ds->priv;
106+
107+ priv->info->phy_write(ds, port_num, reg_addr, write_data);
108+}
109+
110+static u32 switch_phy_read(struct dsa_switch *ds, u32 port_num, u32 reg_addr){
111+ struct mt7530_priv *priv = ds->priv;
112+
113+ return priv->info->phy_read(ds, port_num, reg_addr);
114+}
115+
116+static void mt753x_tr_write(struct dsa_switch *ds, int addr, u8 ch, u8 node, u8 daddr,
117+ u32 data)
118+{
119+ ktime_t timeout;
120+ u32 timeout_us;
121+ u32 val;
122+
123+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);
124+
125+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
126+
127+ timeout_us = 100000;
128+ timeout = ktime_add_us(ktime_get(), timeout_us);
129+ while (1) {
130+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
131+
132+ if (!!(val & PHY_TR_PKT_XMT_STA))
133+ break;
134+
135+ if (ktime_compare(ktime_get(), timeout) > 0)
136+ goto out;
137+ }
138+
139+ switch_phy_write(ds, addr, PHY_TR_LOW_DATA, PHY_TR_LOW_VAL(data));
140+ switch_phy_write(ds, addr, PHY_TR_HIGH_DATA, PHY_TR_HIGH_VAL(data));
141+ val = PHY_TR_PKT_XMT_STA | (PHY_TR_WRITE << PHY_TR_WR_S) |
142+ (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
143+ (daddr << PHY_TR_DATA_ADDR_S);
144+ switch_phy_write(ds, addr, PHY_TR_CTRL, val);
145+
146+ timeout_us = 100000;
147+ timeout = ktime_add_us(ktime_get(), timeout_us);
148+ while (1) {
149+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
150+
151+ if (!!(val & PHY_TR_PKT_XMT_STA))
152+ break;
153+
154+ if (ktime_compare(ktime_get(), timeout) > 0)
155+ goto out;
156+ }
157+out:
158+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
159+}
160+
161+static int mt753x_tr_read(struct dsa_switch *ds, int addr, u8 ch, u8 node, u8 daddr)
162+{
163+ ktime_t timeout;
164+ u32 timeout_us;
165+ u32 val;
166+ u8 val_h;
167+
168+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);
169+
170+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
171+
172+ timeout_us = 100000;
173+ timeout = ktime_add_us(ktime_get(), timeout_us);
174+ while (1) {
175+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
176+
177+ if (!!(val & PHY_TR_PKT_XMT_STA))
178+ break;
179+
180+ if (ktime_compare(ktime_get(), timeout) > 0) {
181+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
182+ return -ETIMEDOUT;
183+ }
184+ }
185+
186+ val = PHY_TR_PKT_XMT_STA | (PHY_TR_READ << PHY_TR_WR_S) |
187+ (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
188+ (daddr << PHY_TR_DATA_ADDR_S);
189+ switch_phy_write(ds, addr, PHY_TR_CTRL, val);
190+
191+ timeout_us = 100000;
192+ timeout = ktime_add_us(ktime_get(), timeout_us);
193+ while (1) {
194+ val = switch_phy_read(ds, addr, PHY_TR_CTRL);
195+
196+ if (!!(val & PHY_TR_PKT_XMT_STA))
197+ break;
198+
199+ if (ktime_compare(ktime_get(), timeout) > 0) {
200+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
201+ return -ETIMEDOUT;
202+ }
203+ }
204+
205+ val = switch_phy_read(ds, addr, PHY_TR_LOW_DATA);
206+ val_h = switch_phy_read(ds, addr, PHY_TR_HIGH_DATA);
207+ val |= (val_h << 16);
208+
209+ switch_phy_write(ds, addr, PHY_CL22_PAGE_CTRL, 0);
210+
211+ return val;
212+}
213+
214+static const u8 MT753x_ZCAL_TO_R50ohm_GE_TBL_100[64] = {
215+ 127, 127, 127, 127, 127, 127, 127, 127,
216+ 127, 127, 127, 127, 127, 123, 122, 117,
217+ 115, 112, 103, 100, 98, 87, 85, 83,
218+ 81, 72, 70, 68, 66, 64, 55, 53,
219+ 52, 50, 49, 48, 38, 36, 35, 34,
220+ 33, 32, 22, 21, 20, 19, 18, 17,
221+ 16, 7, 6, 5, 4, 3, 2, 1,
222+ 0, 0, 0, 0, 0, 0, 0, 0
223+};
224+
225+static const u8 MT753x_TX_OFFSET_TBL[64] = {
226+ 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
227+ 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
228+ 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,
229+ 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
230+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
231+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
232+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
233+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
234+};
235+
236+static u8 ge_cal_flag;
237+
238+static u8 all_ge_ana_cal_wait(struct dsa_switch *ds, u32 delay, u32 phyaddr)
239+{
240+ u8 all_ana_cal_status;
241+ u32 cnt, tmp_1e_17c;
242+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017c, 0x0001); // da_calin_flag pull high
243+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
244+ //printk("delay = %d\n", delay);
245+
246+ cnt = 10000;
247+ do {
248+ udelay(delay);
249+ cnt--;
250+ all_ana_cal_status = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17b) & 0x1;
251+
252+ } while ((all_ana_cal_status == 0) && (cnt != 0));
253+
254+
255+ if(all_ana_cal_status == 1) {
256+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
257+ return all_ana_cal_status;
258+ } else {
259+ tmp_1e_17c = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c);
260+ if ((tmp_1e_17c & 0x1) != 1) {
261+ pr_info("FIRST MDC/MDIO write error\n");
262+ pr_info("FIRST 1e_17c = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c));
263+
264+ }
265+ printk("re-K again\n");
266+
267+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
268+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
269+ cnt = 10000;
270+ do {
271+ udelay(delay);
272+ cnt--;
273+ tmp_1e_17c = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c);
274+ if ((tmp_1e_17c & 0x1) != 1) {
275+ pr_info("SECOND MDC/MDIO write error\n");
276+ pr_info("SECOND 1e_17c = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17c));
277+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
278+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
279+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0x0001);
280+ }
281+ } while ((cnt != 0) && (tmp_1e_17c == 0));
282+
283+ cnt = 10000;
284+ do {
285+ udelay(delay);
286+ cnt--;
287+ all_ana_cal_status = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x17b) & 0x1;
288+
289+ } while ((all_ana_cal_status == 0) && (cnt != 0));
290+
291+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x17c, 0);
292+ }
293+
294+ if(all_ana_cal_status == 0){
295+ pr_info("!!!!!!!!!!!! dev1Eh_reg17b ERROR\n");
296+ }
297+
298+ return all_ana_cal_status;
299+}
300+
301+
302+
303+
304+static int ge_cal_rext(struct dsa_switch *ds, u8 phyaddr, u32 delay)
305+{
306+ u8 rg_zcal_ctrl, all_ana_cal_status;
307+ u16 ad_cal_comp_out_init;
308+ u16 dev1e_e0_ana_cal_r5;
309+ int calibration_polarity;
310+ u8 cnt = 0;
311+ u16 dev1e_17a_tmp, dev1e_e0_tmp;
312+
313+ /* *** Iext/Rext Cal start ************ */
314+ all_ana_cal_status = ANACAL_INIT;
315+ /* analog calibration enable, Rext calibration enable */
316+ /* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */
317+ /* 1e_dc[0]:rg_txvos_calen */
318+ /* 1e_e1[4]:rg_cal_refsel(0:1.2V) */
319+ //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00db, 0x1110)
320+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x1110);
321+ //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00dc, 0x0000);
322+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0);
323+ //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00e1, 0x0000);
324+ //tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x10);
325+
326+ rg_zcal_ctrl = 0x20;/* start with 0 dB */
327+ dev1e_e0_ana_cal_r5 = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0xe0); // get default value
328+ /* 1e_e0[5:0]:rg_zcal_ctrl */
329+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0xe0, rg_zcal_ctrl);
330+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr);/* delay 20 usec */
331+
332+ if (all_ana_cal_status == 0) {
333+ all_ana_cal_status = ANACAL_ERROR;
334+ printk(" GE Rext AnaCal ERROR init! \r\n");
335+ return -1;
336+ }
337+ /* 1e_17a[8]:ad_cal_comp_out */
338+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a) >> 8) & 0x1;
339+ if (ad_cal_comp_out_init == 1)
340+ calibration_polarity = -1;
341+ else /* ad_cal_comp_out_init == 0 */
342+ calibration_polarity = 1;
343+ cnt = 0;
344+ while (all_ana_cal_status < ANACAL_ERROR) {
345+ cnt++;
346+ rg_zcal_ctrl += calibration_polarity;
347+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0xe0, (rg_zcal_ctrl));
348+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); /* delay 20 usec */
349+ dev1e_17a_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a);
350+ if (all_ana_cal_status == 0) {
351+ all_ana_cal_status = ANACAL_ERROR;
352+ printk(" GE Rext AnaCal ERROR 2! \r\n");
353+ return -1;
354+ } else if (((dev1e_17a_tmp >> 8) & 0x1) != ad_cal_comp_out_init) {
355+ all_ana_cal_status = ANACAL_FINISH;
356+ //printk(" GE Rext AnaCal Done! (%d)(0x%x) \r\n", cnt, rg_zcal_ctrl);
357+ } else {
358+ dev1e_17a_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a);
359+ dev1e_e0_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0xe0);
360+ if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) {
361+ all_ana_cal_status = ANACAL_SATURATION; /* need to FT(IC fail?) */
362+ printk(" GE Rext AnaCal Saturation! \r\n");
363+ rg_zcal_ctrl = 0x20; /* 0 dB */
364+ }
365+ }
366+ }
367+
368+ if (all_ana_cal_status == ANACAL_ERROR) {
369+ rg_zcal_ctrl = 0x20; /* 0 dB */
370+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
371+ } else if(all_ana_cal_status == ANACAL_FINISH){
372+ //tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
373+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, ((rg_zcal_ctrl << 8) | rg_zcal_ctrl));
374+ printk("0x1e-e0 = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x00e0));
375+ /* **** 1f_115[2:0] = rg_zcal_ctrl[5:3] // Mog review */
376+ tc_phy_write_dev_reg(ds, PHY0, 0x1f, 0x0115, ((rg_zcal_ctrl & 0x3f) >> 3));
377+ printk("0x1f-115 = %x\n", tc_phy_read_dev_reg(ds, PHY0, 0x1f, 0x115));
378+ printk(" GE Rext AnaCal Done! (%d)(0x%x) \r\n", cnt, rg_zcal_ctrl);
379+ ge_cal_flag = 1;
380+ } else {
381+ printk("GE Rxet cal something wrong2\n");
382+ }
383+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
384+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);
385+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);
386+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
387+
388+ return 0;
389+}
390+
391+//-----------------------------------------------------------------
392+static int ge_cal_r50(struct dsa_switch *ds, u8 phyaddr, u32 delay)
393+{
394+ u8 rg_zcal_ctrl, all_ana_cal_status, calibration_pair;
395+ u16 ad_cal_comp_out_init;
396+ u16 dev1e_e0_ana_cal_r5;
397+ int calibration_polarity;
398+ u8 cnt = 0;
399+ 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
400+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000); // 1e_dc[0]:rg_txvos_calen
401+
402+ for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) {
403+ rg_zcal_ctrl = 0x20; // start with 0 dB
404+ dev1e_e0_ana_cal_r5 = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x00e0) & (~0x003f));
405+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); // 1e_e0[5:0]:rg_zcal_ctrl
406+ if(calibration_pair == ANACAL_PAIR_A)
407+ {
408+ 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
409+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
410+ //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));
411+
412+ }
413+ else if(calibration_pair == ANACAL_PAIR_B)
414+ {
415+ 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
416+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x1000); // 1e_dc[12]:rg_zcalen_b
417+ //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));
418+
419+ }
420+ else if(calibration_pair == ANACAL_PAIR_C)
421+ {
422+ 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
423+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0100); // 1e_dc[8]:rg_zcalen_c
424+ //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));
425+
426+ }
427+ else // if(calibration_pair == ANACAL_PAIR_D)
428+ {
429+ 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
430+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0010); // 1e_dc[4]:rg_zcalen_d
431+ //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));
432+
433+ }
434+
435+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
436+ if(all_ana_cal_status == 0)
437+ {
438+ all_ana_cal_status = ANACAL_ERROR;
439+ printk( "GE R50 AnaCal ERROR init! \r\n");
440+ return -1;
441+ }
442+
443+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out
444+ if(ad_cal_comp_out_init == 1)
445+ calibration_polarity = -1;
446+ else
447+ calibration_polarity = 1;
448+
449+ cnt = 0;
450+ while(all_ana_cal_status < ANACAL_ERROR)
451+ {
452+ cnt ++;
453+ rg_zcal_ctrl += calibration_polarity;
454+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
455+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
456+
457+ if(all_ana_cal_status == 0)
458+ {
459+ all_ana_cal_status = ANACAL_ERROR;
460+ printk( " GE R50 AnaCal ERROR 2! \r\n");
461+ return -1;
462+ }
463+ else if(((tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init)
464+ {
465+ all_ana_cal_status = ANACAL_FINISH;
466+ }
467+ else {
468+ if((rg_zcal_ctrl == 0x3F)||(rg_zcal_ctrl == 0x00))
469+ {
470+ all_ana_cal_status = ANACAL_SATURATION; // need to FT
471+ printk( " GE R50 AnaCal Saturation! \r\n");
472+ }
473+ }
474+ }
475+
476+ if(all_ana_cal_status == ANACAL_ERROR) {
477+ rg_zcal_ctrl = 0x20; // 0 dB
478+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl));
479+ }
480+ else {
481+ rg_zcal_ctrl = MT753x_ZCAL_TO_R50ohm_GE_TBL_100[rg_zcal_ctrl - 9]; // wait Mog zcal/r50 mapping table
482+ printk( " GE R50 AnaCal Done! (%d) (0x%x)(0x%x) \r\n", cnt, rg_zcal_ctrl, (rg_zcal_ctrl|0x80));
483+ }
484+
485+ if(calibration_pair == ANACAL_PAIR_A) {
486+ ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0174) & (~0x7f00);
487+ //ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0174);
488+ //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));
489+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); // 1e_174[15:8]
490+ //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));
491+ }
492+ else if(calibration_pair == ANACAL_PAIR_B) {
493+ ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0174) & (~0x007f);
494+ //ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0174);
495+ //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));
496+
497+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); // 1e_174[7:0]
498+ //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));
499+ }
500+ else if(calibration_pair == ANACAL_PAIR_C) {
501+ ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0175) & (~0x7f00);
502+ //ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0175);
503+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); // 1e_175[15:8]
504+ //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));
505+ } else {// if(calibration_pair == ANACAL_PAIR_D)
506+ ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0175) & (~0x007f);
507+ //ad_cal_comp_out_init = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0175);
508+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); // 1e_175[7:0]
509+ //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));
510+ }
511+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00e0, ((rg_zcal_ctrl<<8)|rg_zcal_ctrl));
512+ }
513+
514+ 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));
515+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
516+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000);
517+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000);
518+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000);
519+
520+ return 0;
521+}
522+
523+static int ge_cal_tx_offset(struct dsa_switch *ds, u8 phyaddr, u32 delay)
524+{
525+ u8 all_ana_cal_status, calibration_pair;
526+ u16 ad_cal_comp_out_init;
527+ int calibration_polarity, tx_offset_temp;
528+ u8 tx_offset_reg_shift, tabl_idx, i;
529+ u8 cnt = 0;
530+ u16 tx_offset_reg, reg_temp, cal_temp;
531+ //switch_phy_write(phyaddr, R0, 0x2100);//harry tmp
532+ 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
533+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0001); // 1e_dc[0]:rg_txvos_calen
534+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0096, 0x8000); // 1e_96[15]:bypass_tx_offset_cal, Hw bypass, Fw cal
535+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0xf808); // 1e_3e
536+ for(i = 0; i <= 4; i++)
537+ tc_phy_write_dev_reg(ds, i, 0x1e, 0x00dd, 0x0000);
538+ for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++)
539+ {
540+ tabl_idx = 31;
541+ tx_offset_temp = MT753x_TX_OFFSET_TBL[tabl_idx];
542+
543+ if(calibration_pair == ANACAL_PAIR_A) {
544+ //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x145, 0x5010);
545+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x1000); // 1e_dd[12]:rg_txg_calen_a
546+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_0V)); // 1e_17d:dac_in0_a
547+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_0V)); // 1e_181:dac_in1_a
548+ //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));
549+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0172) & (~0x3f00));
550+ tx_offset_reg_shift = 8; // 1e_172[13:8]
551+ tx_offset_reg = 0x0172;
552+
553+ //tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
554+ } else if(calibration_pair == ANACAL_PAIR_B) {
555+ //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x145, 0x5018);
556+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0100); // 1e_dd[8]:rg_txg_calen_b
557+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_0V)); // 1e_17e:dac_in0_b
558+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_0V)); // 1e_182:dac_in1_b
559+ //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));
560+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0172) & (~0x003f));
561+ tx_offset_reg_shift = 0; // 1e_172[5:0]
562+ tx_offset_reg = 0x0172;
563+ //tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
564+ } else if(calibration_pair == ANACAL_PAIR_C) {
565+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0010); // 1e_dd[4]:rg_txg_calen_c
566+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_0V)); // 1e_17f:dac_in0_c
567+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_0V)); // 1e_183:dac_in1_c
568+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0173) & (~0x3f00));
569+ //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));
570+ tx_offset_reg_shift = 8; // 1e_173[13:8]
571+ tx_offset_reg = 0x0173;
572+ //tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
573+ } else {// if(calibration_pair == ANACAL_PAIR_D)
574+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0001); // 1e_dd[0]:rg_txg_calen_d
575+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_0V)); // 1e_180:dac_in0_d
576+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_0V)); // 1e_184:dac_in1_d
577+ //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));
578+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x0173) & (~0x003f));
579+ tx_offset_reg_shift = 0; // 1e_173[5:0]
580+ tx_offset_reg = 0x0173;
581+ //tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
582+ }
583+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift))); // 1e_172, 1e_173
584+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
585+ if(all_ana_cal_status == 0) {
586+ all_ana_cal_status = ANACAL_ERROR;
587+ printk( " GE Tx offset AnaCal ERROR init! \r\n");
588+ return -1;
589+ }
590+
591+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out
592+ if(ad_cal_comp_out_init == 1)
593+ calibration_polarity = 1;
594+ else
595+ calibration_polarity = -1;
596+
597+ cnt = 0;
598+ //printk("TX offset cnt = %d, tabl_idx= %x, offset_val = %x\n", cnt, tabl_idx, MT753x_TX_OFFSET_TBL[tabl_idx]);
599+ while(all_ana_cal_status < ANACAL_ERROR) {
600+
601+ cnt ++;
602+ tabl_idx += calibration_polarity;
603+ //tx_offset_temp += calibration_polarity;
604+ //cal_temp = tx_offset_temp;
605+ cal_temp = MT753x_TX_OFFSET_TBL[tabl_idx];
606+ //printk("TX offset cnt = %d, tabl_idx= %x, offset_val = %x\n", cnt, tabl_idx, MT753x_TX_OFFSET_TBL[tabl_idx]);
607+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(cal_temp<<tx_offset_reg_shift)));
608+
609+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
610+ if(all_ana_cal_status == 0) {
611+ all_ana_cal_status = ANACAL_ERROR;
612+ printk( " GE Tx offset AnaCal ERROR init 2! \r\n");
613+ return -1;
614+ } else if(((tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init) {
615+ all_ana_cal_status = ANACAL_FINISH;
616+ } else {
617+ if((tabl_idx == 0)||(tabl_idx == 0x3f)) {
618+ all_ana_cal_status = ANACAL_SATURATION; // need to FT
619+ printk( " GE Tx offset AnaCal Saturation! \r\n");
620+ }
621+ }
622+ }
623+
624+ if(all_ana_cal_status == ANACAL_ERROR) {
625+ tx_offset_temp = TX_AMP_OFFSET_0MV;
626+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<<tx_offset_reg_shift)));
627+ } else {
628+ 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));
629+ }
630+ }
631+
632+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, 0x0000);
633+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, 0x0000);
634+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, 0x0000);
635+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, 0x0000);
636+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, 0x0000);
637+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, 0x0000);
638+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, 0x0000);
639+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, 0x0000);
640+
641+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit
642+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit
643+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit
644+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit
645+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0x0000); // disable Tx VLD force mode
646+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0000); // disable Tx offset/amplitude calibration circuit
647+
648+ return 0;
649+}
650+
651+u16 tx_amp_check_thres(int pair, u32 reg, u16 val, s16 offset)
652+{
653+ if ((offset < 0 && (0 - offset) > TX_AMP_MAX_OFFSET) ||
654+ (offset > TX_AMP_MAX_OFFSET)) {
655+ pr_info(" offset=%d exceed tx amp max offset=%d\n", offset, TX_AMP_MAX_OFFSET);
656+ return val;
657+ }
658+
659+ if (offset < 0 && val < TX_AMP_LOW_TS - offset) {
660+ if (val < TX_AMP_LOWEST_TS - offset) {
661+ pr_info(" GE Tx amp AnaCal underflow! (pair-%d)(1e_%x) seed 0x%x < 0x%x)\n",
662+ pair, reg, val, TX_AMP_LOWEST_TS - offset);
663+ }
664+ return 0;
665+ }
666+
667+ if (offset >= 0 && val > TX_AMP_HIGH_TS - offset) {
668+ if ( val > TX_AMP_HIGHEST_TS - offset) {
669+ pr_info(" GE Tx amp AnaCal overflow! (pair-%d)(1e_%x) seed = 0x%x > 0x%x)\n",
670+ pair, reg, val, TX_AMP_HIGHEST_TS - offset);
671+ }
672+ return TX_AMP_MAX;
673+ }
674+
675+ return val + offset;
676+}
677+
678+static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
679+{
680+ u8 all_ana_cal_status, calibration_pair, i;
681+ u16 ad_cal_comp_out_init;
682+ int calibration_polarity;
683+ u32 tx_amp_reg_shift;
684+ u16 reg_temp;
685+ u32 tx_amp_temp, tx_amp_reg, cnt=0, tx_amp_reg_100;
686+ u32 debug_tmp, reg_backup, reg_tmp;
687+ u32 orig_1e_11, orig_1f_300;
688+
689+ 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
690+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0001); // 1e_dc[0]:rg_txvos_calen
691+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x0010); // 1e_e1[4]:select 1V
692+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0xf808); // 1e_3e:enable Tx VLD
693+
694+ orig_1e_11 = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x11);
695+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, 0xff00);
696+// tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27a, 0x33);
697+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0xc9, 0xffff);
698+ orig_1f_300 = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x300);
699+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x300, 0x4);
700+ for(i = 0; i <= 4; i++)
701+ tc_phy_write_dev_reg(ds, i, 0x1e, 0x00dd, 0x0000);
702+ for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) {
703+ tx_amp_temp = 0x20; // start with 0 dB
704+
705+ if(calibration_pair == ANACAL_PAIR_A) {
706+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x1000); // 1e_dd[12]:tx_a amp calibration enable
707+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_2V)); // 1e_17d:dac_in0_a
708+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_2V)); // 1e_181:dac_in1_a
709+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x012) & (~0xfc00));
710+ tx_amp_reg_shift = 10; // 1e_12[15:10]
711+ tx_amp_reg = 0x12;
712+ tx_amp_reg_100 = 0x16;
713+ } else if(calibration_pair == ANACAL_PAIR_B) {
714+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0100); // 1e_dd[8]:tx_b amp calibration enable
715+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_2V)); // 1e_17e:dac_in0_b
716+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_2V)); // 1e_182:dac_in1_b
717+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x017) & (~0x3f00));
718+ tx_amp_reg_shift = 8; // 1e_17[13:8]
719+ tx_amp_reg = 0x17;
720+ tx_amp_reg_100 = 0x18;
721+ } else if(calibration_pair == ANACAL_PAIR_C) {
722+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0010); // 1e_dd[4]:tx_c amp calibration enable
723+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_2V)); // 1e_17f:dac_in0_c
724+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_2V)); // 1e_183:dac_in1_c
725+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x019) & (~0x3f00));
726+ tx_amp_reg_shift = 8; // 1e_19[13:8]
727+ tx_amp_reg = 0x19;
728+ tx_amp_reg_100 = 0x20;
729+ } else { //if(calibration_pair == ANACAL_PAIR_D)
730+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0001); // 1e_dd[0]:tx_d amp calibration enable
731+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_2V)); // 1e_180:dac_in0_d
732+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_2V)); // 1e_184:dac_in1_d
733+ reg_temp = (tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x021) & (~0x3f00));
734+ tx_amp_reg_shift = 8; // 1e_21[13:8]
735+ tx_amp_reg = 0x21;
736+ tx_amp_reg_100 = 0x22;
737+ }
738+ 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
739+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
740+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
741+ if(all_ana_cal_status == 0) {
742+ all_ana_cal_status = ANACAL_ERROR;
743+ printk( " GE Tx amp AnaCal ERROR init init! \r\n");
744+ return -1;
745+ }
746+
747+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out
748+ if(ad_cal_comp_out_init == 1)
749+ calibration_polarity = -1;
750+ else
751+ calibration_polarity = 1;
752+
753+ cnt =0;
754+ while(all_ana_cal_status < ANACAL_ERROR) {
755+ cnt ++;
756+ tx_amp_temp += calibration_polarity;
757+ //printk("tx_amp : %x, 1e %x = %x\n", tx_amp_temp, tx_amp_reg, (reg_temp|(tx_amp_temp<<tx_amp_reg_shift)));
758+ tc_phy_write_dev_reg( ds, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
759+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100, (tx_amp_temp|(tx_amp_temp<<tx_amp_reg_shift)));
760+ all_ana_cal_status = all_ge_ana_cal_wait(ds, delay, phyaddr); // delay 20 usec
761+ if(all_ana_cal_status == 0) {
762+ all_ana_cal_status = ANACAL_ERROR;
763+ printk( " GE Tx amp AnaCal ERROR 2! \r\n");
764+ return -1;
765+ } else if(((tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x017a)>>8)&0x1) != ad_cal_comp_out_init) {
766+ //printk("TX AMP ANACAL_FINISH\n");
767+ all_ana_cal_status = ANACAL_FINISH;
768+ if (phyaddr == 0) {
769+ if (calibration_pair == ANACAL_PAIR_A)
770+ tx_amp_temp = tx_amp_temp - 2;
771+ else if(calibration_pair == ANACAL_PAIR_B)
772+ tx_amp_temp = tx_amp_temp - 1;
773+ else if(calibration_pair == ANACAL_PAIR_C)
774+ tx_amp_temp = tx_amp_temp - 2;
775+ else if(calibration_pair == ANACAL_PAIR_D)
776+ tx_amp_temp = tx_amp_temp - 1;
777+ } else if (phyaddr == 1) {
778+ if (calibration_pair == ANACAL_PAIR_A)
779+ tx_amp_temp = tx_amp_temp - 1;
780+ else if(calibration_pair == ANACAL_PAIR_B)
781+ tx_amp_temp = tx_amp_temp ;
782+ else if(calibration_pair == ANACAL_PAIR_C)
783+ tx_amp_temp = tx_amp_temp - 1;
784+ else if(calibration_pair == ANACAL_PAIR_D)
785+ tx_amp_temp = tx_amp_temp - 1;
786+ } else if (phyaddr == 2) {
787+ if (calibration_pair == ANACAL_PAIR_A)
788+ tx_amp_temp = tx_amp_temp;
789+ else if(calibration_pair == ANACAL_PAIR_B)
790+ tx_amp_temp = tx_amp_temp - 1;
791+ else if(calibration_pair == ANACAL_PAIR_C)
792+ tx_amp_temp = tx_amp_temp;
793+ else if(calibration_pair == ANACAL_PAIR_D)
794+ tx_amp_temp = tx_amp_temp - 1;
795+ } else if (phyaddr == 3) {
796+ tx_amp_temp = tx_amp_temp;
797+ } else if (phyaddr == 4) {
798+ if (calibration_pair == ANACAL_PAIR_A)
799+ tx_amp_temp = tx_amp_temp;
800+ else if(calibration_pair == ANACAL_PAIR_B)
801+ tx_amp_temp = tx_amp_temp - 1;
802+ else if(calibration_pair == ANACAL_PAIR_C)
803+ tx_amp_temp = tx_amp_temp;
804+ else if(calibration_pair == ANACAL_PAIR_D)
805+ tx_amp_temp = tx_amp_temp;
806+ }
807+ reg_temp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg)&(~0xff00);
808+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
809+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
810+ if (phyaddr == 0) {
811+ if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
812+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
813+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
814+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
815+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
816+ }
817+ if (tx_amp_reg_100 == 0x16) {
818+ //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));
819+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 1+4);
820+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
821+ //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));
822+ }
823+ if (tx_amp_reg_100 == 0x18) {
824+ //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));
825+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 4);
826+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
827+ //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));
828+ }
829+ } else if (phyaddr == 1) {
830+ if (tx_amp_reg == 0x12) {
831+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
832+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 9);
833+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
834+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
835+ }
836+ if (tx_amp_reg == 0x17){
837+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
838+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
839+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
840+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
841+ }
842+ if (tx_amp_reg_100 == 0x16) {
843+ //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));
844+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, 4);
845+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
846+ //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));
847+ }
848+ if (tx_amp_reg_100 == 0x18) {
849+ //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));
850+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
851+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
852+ //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));
853+ }
854+ } else if (phyaddr == 2) {
855+ if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
856+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
857+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 6);
858+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
859+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
860+ }
861+ if ((tx_amp_reg_100 == 0x16) || (tx_amp_reg_100 == 0x18)) {
862+ //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));
863+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
864+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
865+ //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));
866+ }
867+ } else if (phyaddr == 3) {
868+ if (tx_amp_reg == 0x12) {
869+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
870+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 4);
871+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
872+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
873+ }
874+ if (tx_amp_reg == 0x17) {
875+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
876+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 7);
877+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
878+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
879+ }
880+ if (tx_amp_reg_100 == 0x16) {
881+ //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));
882+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -2+4);
883+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
884+ //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));
885+ }
886+ if (tx_amp_reg_100 == 0x18) {
887+ //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));
888+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+3);
889+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
890+ //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));
891+ }
892+ } else if (phyaddr == 4) {
893+ if ((tx_amp_reg == 0x12) || (tx_amp_reg == 0x17)) {
894+ //printk("before : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
895+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg, tx_amp_temp, 5);
896+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, ((reg_tmp|((tx_amp_temp)<<tx_amp_reg_shift))));
897+ //printk("after : PORT[%d] 1e_%x = %x\n", phyaddr, tx_amp_reg, tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg));
898+ }
899+ if (tx_amp_reg_100 == 0x16) {
900+ //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));
901+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -2+4);
902+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
903+ //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));
904+ }
905+ if (tx_amp_reg_100 == 0x18) {
906+ //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));
907+ reg_tmp = tx_amp_check_thres(calibration_pair, tx_amp_reg_100, tx_amp_temp, -1+4);
908+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((reg_tmp)<<tx_amp_reg_shift)));
909+ //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));
910+ }
developerf3ac1552021-07-07 10:01:50 +0800911+ }
developer24091172021-07-06 16:36:48 +0800912+
913+ if (calibration_pair == ANACAL_PAIR_A){
914+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x12);
915+ reg_tmp = ((reg_backup & 0xfc00) >> 10);
916+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
917+ reg_backup = 0x0000;
918+ reg_backup |= ((tx_amp_temp << 10) | (tx_amp_temp << 0));
919+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x12, reg_backup);
920+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x12);
921+ //printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup);
922+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x16);
923+ reg_tmp = ((reg_backup & 0x3f) >> 0);
924+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
925+ reg_backup = (reg_backup & (~0x3f));
926+ reg_backup |= (tx_amp_temp << 0);
927+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x16, reg_backup);
928+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x16);
929+ //printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup);
930+ }
931+ else if(calibration_pair == ANACAL_PAIR_B){
932+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x17);
933+ reg_tmp = ((reg_backup & 0x3f00) >> 8);
934+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
935+ reg_backup = 0x0000;
936+ reg_backup |= ((tx_amp_temp << 8) | (tx_amp_temp << 0));
937+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x17, reg_backup);
938+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x17);
939+ //printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup);
940+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x18);
941+ reg_tmp = ((reg_backup & 0x3f) >> 0);
942+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
943+ reg_backup = (reg_backup & (~0x3f));
944+ reg_backup |= (tx_amp_temp << 0);
945+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18, reg_backup);
946+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x18);
947+ //printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup);
948+ }
949+ else if(calibration_pair == ANACAL_PAIR_C){
950+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x19);
951+ reg_tmp = ((reg_backup & 0x3f00) >> 8);
952+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
953+ reg_backup = (reg_backup & (~0x3f00));
954+ reg_backup |= (tx_amp_temp << 8);
955+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x19, reg_backup);
956+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x19);
957+ //printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup);
958+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x20);
959+ reg_tmp = ((reg_backup & 0x3f) >> 0);
960+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
961+ reg_backup = (reg_backup & (~0x3f));
962+ reg_backup |= (tx_amp_temp << 0);
963+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x20, reg_backup);
964+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x20);
965+ //printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup);
966+ }
967+ else if(calibration_pair == ANACAL_PAIR_D){
968+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x21);
969+ reg_tmp = ((reg_backup & 0x3f00) >> 8);
970+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
971+ reg_backup = (reg_backup & (~0x3f00));
972+ reg_backup |= (tx_amp_temp << 8);
973+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x21, reg_backup);
974+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x21);
975+ //printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup);
976+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x22);
977+ reg_tmp = ((reg_backup & 0x3f) >> 0);
978+ tx_amp_temp = tx_amp_check_thres(calibration_pair, tx_amp_reg, reg_tmp, -8);
979+ reg_backup = (reg_backup & (~0x3f));
980+ reg_backup |= (tx_amp_temp << 0);
981+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x22, reg_backup);
982+ reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x22);
983+ //printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup);
984+ }
985+
986+ if (calibration_pair == ANACAL_PAIR_A){
987+ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
988+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x12);
989+ //printk("1e.012 = 0x%x\n", debug_tmp);
990+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x16);
991+ //printk("1e.016 = 0x%x\n", debug_tmp);
992+ }
993+
994+ else if(calibration_pair == ANACAL_PAIR_B){
995+ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
996+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x17);
997+ //printk("1e.017 = 0x%x\n", debug_tmp);
998+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x18);
999+ //printk("1e.018 = 0x%x\n", debug_tmp);
1000+ }
1001+ else if(calibration_pair == ANACAL_PAIR_C){
1002+ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
1003+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x19);
1004+ //printk("1e.019 = 0x%x\n", debug_tmp);
1005+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x20);
1006+ //printk("1e.020 = 0x%x\n", debug_tmp);
1007+ }
1008+ else if(calibration_pair == ANACAL_PAIR_D){
1009+ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr);
1010+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x21);
1011+ //printk("1e.021 = 0x%x\n", debug_tmp);
1012+ debug_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x22);
1013+ //printk("1e.022 = 0x%x\n", debug_tmp);
1014+ }
1015+
1016+
1017+ 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);
1018+
1019+ } else {
1020+ if((tx_amp_temp == 0x3f)||(tx_amp_temp == 0x00)) {
1021+ all_ana_cal_status = ANACAL_SATURATION; // need to FT
1022+ printk( " GE Tx amp AnaCal Saturation! \r\n");
1023+ }
1024+ }
1025+ }
1026+
1027+ if(all_ana_cal_status == ANACAL_ERROR) {
1028+ tx_amp_temp = 0x20;
1029+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg, (reg_temp|(tx_amp_temp<<tx_amp_reg_shift)));
1030+ }
1031+ }
1032+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017d, 0x0000);
1033+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017e, 0x0000);
1034+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x017f, 0x0000);
1035+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0180, 0x0000);
1036+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0181, 0x0000);
1037+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0182, 0x0000);
1038+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0183, 0x0000);
1039+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x0184, 0x0000);
1040+
1041+ /* disable analog calibration circuit */
1042+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00db, 0x0000);
1043+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit
1044+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit
1045+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit
1046+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x003e, 0x0000); // disable Tx VLD force mode
1047+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x00dd, 0x0000); // disable Tx offset/amplitude calibration circuit
1048+
1049+
1050+
1051+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x2000);
1052+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0xc9, 0x0fff);
1053+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x145, 0x1000);
1054+
1055+ /* Restore CR to default */
1056+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, orig_1e_11);
1057+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x300, orig_1f_300);
1058+
1059+ return 0;
1060+}
1061+
1062+//-----------------------------------------------------------------
1063+
1064+static int phy_calibration(struct dsa_switch *ds, u8 phyaddr)
1065+{
1066+ //u32 reg_tmp,reg_tmp0, reg_tmp1, i;
1067+ u32 reg_tmp;
1068+ u32 CALDLY = 40;
1069+ u32 orig_1e_11, orig_1e_185, orig_1e_e1, orig_1f_100;
1070+ int ret;
1071+
1072+ /* Use SW calibration data. */
1073+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x403);
1074+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x403, reg_tmp | BIT(3));
1075+ /* set [12]AN disable, [8]full duplex, [13/6]1000Mbps */
1076+ //tc_phy_write_dev_reg(phyaddr, 0x0, 0x0140);
1077+ switch_phy_write(ds, phyaddr, R0, 0x140);
1078+
1079+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x145, 0x1010);/* fix mdi */
1080+ orig_1e_185 = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, RG_185);
1081+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, RG_185, 0);/* disable tx slew control */
1082+ orig_1f_100 = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x100);
1083+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x100, 0xc000);/* BG voltage output */
1084+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x403, 0x1099); //bypass efuse
1085+
1086+#if (1)
1087+ // 1f_27c[12:8] cr_da_tx_i2mpb_10m Trimming TX bias setup(@10M)
1088+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x1f1f);
1089+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x3300);
1090+
1091+ //reg_tmp1 = tc_phy_read_dev_reg(ds, PHY0, 0x1f, 0x27c);
1092+ //dev1Fh_reg273h TXVLD DA register - Adjust voltage mode TX amplitude.
1093+ //tc_phy_write_dev_reg(phyaddr, 0x1f, 0x273, 0);
1094+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x1000);
1095+ //reg_tmp1 = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x273);
1096+ //printk("reg_tmp1273 = %x\n", reg_tmp1);
1097+ /*1e_11 TX overshoot Enable (PAIR A/B/C/D) in gbe mode*/
1098+
1099+ orig_1e_11 = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x11);
1100+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x11);
1101+ reg_tmp = reg_tmp | (0xf << 12);
1102+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, reg_tmp);
1103+ orig_1e_e1 = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0x00e1);
1104+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, 0x10);
1105+ /* calibration start ============ */
1106+ printk("CALDLY = %d\n", CALDLY);
1107+ if(ge_cal_flag == 0){
1108+ ret = ge_cal_rext(ds, 0, CALDLY);
1109+ if (ret == -1){
1110+ printk("ge_cal_rext error K port =%d\n", phyaddr);
1111+ return ret;
1112+ }
1113+ ge_cal_flag = 1;
1114+ }
1115+
1116+ /* *** R50 Cal start ***************************** */
1117+ /*phyaddress = 0*/
1118+ ret = ge_cal_r50(ds, phyaddr, CALDLY);
1119+ if (ret == -1){
1120+ printk("R50 error K port =%d\n", phyaddr);
1121+ return ret;
1122+ }
1123+ /* *** R50 Cal end *** */
1124+ /* *** Tx offset Cal start *********************** */
1125+ ret = ge_cal_tx_offset(ds, phyaddr, CALDLY);
1126+ if (ret == -1){
1127+ printk("ge_cal_tx_offset error K port =%d\n", phyaddr);
1128+ return ret;
1129+ }
1130+ /* *** Tx offset Cal end *** */
1131+
1132+ /* *** Tx Amp Cal start *** */
1133+ ret = ge_cal_tx_amp(ds, phyaddr, CALDLY);
1134+ if (ret == -1){
1135+ printk("ge_cal_tx_amp error K port =%d\n", phyaddr);
1136+ return ret;
1137+ }
1138+ /* *** Tx Amp Cal end *** */
1139+ /*tmp maybe changed*/
1140+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27c, 0x1111);
1141+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x27b, 0x47);
1142+ //tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x273, 0x2000);
1143+
1144+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3a8, 0x0810);
1145+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3aa, 0x0008);
1146+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ab, 0x0810);
1147+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ad, 0x0008);
1148+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3ae, 0x0106);
1149+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b0, 0x0001);
1150+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b1, 0x0106);
1151+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3b3, 0x0001);
1152+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18c, 0x0001);
1153+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18d, 0x0001);
1154+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18e, 0x0001);
1155+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18f, 0x0001);
1156+
1157+ /*da_tx_bias1_b_tx_standby = 5'b10 (dev1eh_reg3aah[12:8])*/
1158+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x3aa);
1159+ reg_tmp = reg_tmp & ~(0x1f00);
1160+ reg_tmp = reg_tmp | 0x2 << 8;
1161+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3aa, reg_tmp);
1162+
1163+ /*da_tx_bias1_a_tx_standby = 5'b10 (dev1eh_reg3a9h[4:0])*/
1164+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x3a9);
1165+ reg_tmp = reg_tmp & ~(0x1f);
1166+ reg_tmp = reg_tmp | 0x2;
1167+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x3a9, reg_tmp);
1168+
1169+ /* Restore CR to default */
1170+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, RG_185, orig_1e_185);
1171+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x100, orig_1f_100);
1172+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x11, orig_1e_11);
1173+ tc_phy_write_dev_reg(ds, PHY0, 0x1e, 0x00e1, orig_1e_e1);
1174+#endif
1175+ return 0;
1176+}
1177+
1178+static void rx_dc_offset(struct dsa_switch *ds, u8 phyaddr)
1179+{
1180+ pr_info("PORT %d RX_DC_OFFSET\n", phyaddr);
1181+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x96, 0x8000);
1182+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x37, 0x3);
1183+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x107, 0x4000);
1184+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x171, 0x1e5);
1185+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x39, 0x200f);
1186+ udelay(40);
1187+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x39, 0x000f);
1188+ udelay(40);
1189+ tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x171, 0x65);
1190+}
1191+
1192+static void check_rx_dc_offset_pair_a(struct dsa_switch *ds, u8 phyaddr)
1193+{
1194+ u32 reg_tmp;
1195+
1196+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x114f);
1197+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1198+ reg_tmp = reg_tmp & 0xff;
1199+ pr_info("before pairA output = %x\n", reg_tmp);
1200+ udelay(40);
1201+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1142);
1202+ udelay(40);
1203+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1204+ reg_tmp = reg_tmp & 0xff;
1205+ pr_info("after pairA output = %x\n", reg_tmp);
1206+ if ((reg_tmp & 0x80) != 0)
1207+ reg_tmp = (~reg_tmp) + 1;
1208+ if ((reg_tmp & 0xff) >4)
1209+ pr_info("pairA RX_DC_OFFSET error");
1210+}
1211+
1212+static void check_rx_dc_offset_pair_b(struct dsa_switch *ds, u8 phyaddr)
1213+{
1214+ u32 reg_tmp;
1215+
1216+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1151);
1217+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1218+ reg_tmp = reg_tmp & 0xff;
1219+ pr_info("before pairB output = %x\n", reg_tmp);
1220+ udelay(40);
1221+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1143);
1222+ udelay(40);
1223+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1224+ reg_tmp = reg_tmp & 0xff;
1225+ pr_info("after pairB output = %x\n", reg_tmp);
1226+ if ((reg_tmp & 0x80) != 0)
1227+ reg_tmp = (~reg_tmp) + 1;
1228+ if ((reg_tmp & 0xff) >4)
1229+ pr_info("pairB RX_DC_OFFSET error");
1230+}
1231+
1232+static void check_rx_dc_offset_pair_c(struct dsa_switch *ds, u8 phyaddr)
1233+{
1234+ u32 reg_tmp;
1235+
1236+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1153);
1237+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1238+ reg_tmp = reg_tmp & 0xff;
1239+ pr_info("before pairC output = %x\n", reg_tmp);
1240+ udelay(40);
1241+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1144);
1242+ udelay(40);
1243+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1244+ reg_tmp = reg_tmp & 0xff;
1245+ pr_info("after pairC output = %x\n", reg_tmp);
1246+ if ((reg_tmp & 0x80) != 0)
1247+ reg_tmp = (~reg_tmp) + 1;
1248+ if ((reg_tmp & 0xff) >4)
1249+ pr_info("pairC RX_DC_OFFSET error");
1250+}
1251+
1252+static void check_rx_dc_offset_pair_d(struct dsa_switch *ds, u8 phyaddr)
1253+{
1254+ u32 reg_tmp;
1255+
1256+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1155);
1257+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1258+ reg_tmp = reg_tmp & 0xff;
1259+ pr_info("before pairD output = %x\n", reg_tmp);
1260+ udelay(40);
1261+ tc_phy_write_dev_reg(ds, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1145);
1262+ udelay(40);
1263+ reg_tmp = tc_phy_read_dev_reg(ds, phyaddr, 0x1f, 0x1a);
1264+ reg_tmp = reg_tmp & 0xff;
1265+ pr_info("after pairD output = %x\n", reg_tmp);
1266+ if ((reg_tmp & 0x80) != 0)
1267+ reg_tmp = (~reg_tmp) + 1;
1268+ if ((reg_tmp & 0xff) >4)
1269+ pr_info("pairD RX_DC_OFFSET error");
1270+}
1271+
1272+/* 12 registers for TX_MLT3 waveform tuning.
1273+ * 012 345 678 9ab
1274+ * 1 __
1275+ * _/ \_
1276+ * 0_/ \
1277+ * \_ _/
1278+ * -1 \__/
1279+ */
1280+static void mt7531_phy_100m_eye_diag_setting(struct dsa_switch *ds, u32 port)
1281+{
1282+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x0, 0x187);
1283+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x1, 0x1c9);
1284+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x2, 0x1c6);
1285+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x3, 0x182);
1286+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x4, 0x208);
1287+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x5, 0x205);
1288+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x6, 0x384);
1289+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x7, 0x3cb);
1290+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x8, 0x3c4);
1291+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0x9, 0x30a);
1292+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0xa, 0x00b);
1293+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_TX_MLT3_BASE + 0xb, 0x002);
1294+}
1295+
1296+static void mt7531_phy_setting(struct dsa_switch *ds)
1297+{
1298+ int i;
1299+ u32 val;
1300+
1301+ for (i = 0; i < MT7531_NUM_PHYS; i++) {
1302+ mt7531_phy_100m_eye_diag_setting(ds, i);
1303+
1304+ /* Enable HW auto downshift */
1305+ switch_phy_write(ds, i, 0x1f, 0x1);
1306+ val = switch_phy_read(ds, i, PHY_EXT_REG_14);
1307+ val |= PHY_EN_DOWN_SHFIT;
1308+ switch_phy_write(ds, i, PHY_EXT_REG_14, val);
1309+
1310+ /* Decrease SlvDPSready time */
1311+ val = mt753x_tr_read(ds, i, PMA_CH, PMA_NOD, PMA_17);
1312+ val &= ~SLV_DSP_READY_TIME_M;
1313+ val |= 0xc << SLV_DSP_READY_TIME_S;
1314+ mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_17, val);
1315+
1316+ /* Enable Random Update Mechanism */
1317+ val = mt753x_tr_read(ds, i, PMA_CH, PMA_NOD, PMA_18);
1318+ val |= ENABLE_RANDOM_UPDATE_TRIGGER;
1319+ mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_18, val);
1320+
1321+ /* PHY link down power saving enable */
1322+ val = switch_phy_read(ds, i, PHY_EXT_REG_17);
1323+ val |= PHY_LINKDOWN_POWER_SAVING_EN;
1324+ switch_phy_write(ds, i, PHY_EXT_REG_17, val);
1325+
1326+ val = tc_phy_read_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_0C6);
1327+ val &= ~PHY_POWER_SAVING_M;
1328+ val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
1329+ tc_phy_write_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_0C6, val);
1330+
1331+ /* Timing Recovery for GbE slave mode */
1332+ mt753x_tr_write(ds, i, PMA_CH, PMA_NOD, PMA_01, 0x6fb90a);
1333+ mt753x_tr_write(ds, i, DSP_CH, DSP_NOD, DSP_06, 0x2ebaef);
1334+ val = tc_phy_read_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_234);
1335+ val |= TR_OPEN_LOOP_EN;
1336+ tc_phy_write_dev_reg(ds, i, PHY_DEV1E, PHY_DEV1E_REG_234, val);
1337+
1338+ /* Enable Asymmetric Pause Capability */
1339+ val = switch_phy_read(ds, i, MII_ADVERTISE);
1340+ val |= ADVERTISE_PAUSE_ASYM;
1341+ switch_phy_write(ds, i, MII_ADVERTISE, val);
1342+ }
1343+}
1344+
1345+static void mt7531_adjust_line_driving(struct dsa_switch *ds, u32 port)
1346+{
1347+ /* For ADC timing margin window for LDO calibration */
1348+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, RXADC_LDO_CONTROL_2, 0x2222);
1349+
1350+ /* Adjust AD sample timing */
1351+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444);
1352+
1353+ /* Adjust Line driver current for different mode */
1354+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5);
1355+
1356+ /* Adjust Line driver current for different mode */
1357+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b);
1358+
1359+ /* Adjust Line driver gain for 10BT from 1000BT calibration result */
1360+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, TXVLD_DA_273, 0x3000);
1361+
1362+ /* Adjust RX Echo path filter */
1363+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_0FE, 0x2);
1364+
1365+ /* Adjust RX HVGA bias current */
1366+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333);
1367+
1368+ /* Adjust TX class AB driver 1 */
1369+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x384);
1370+
1371+ /* Adjust TX class AB driver 2 */
1372+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x1114);
1373+
1374+ /* Adjust DAC delay for TX Pairs */
1375+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_13, 0x404);
1376+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_14, 0x404);
1377+
1378+ /* Adjust DAC digital delay for TX Delay */
1379+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_44, 0xc0);
1380+
1381+ /* Adjust Line driver compensation cap for stability concern due to
1382+ * increase current.
1383+ */
1384+ tc_phy_write_dev_reg(ds, port, PHY_DEV1F, PHY_DEV1F_REG_26A, 0x3333);
1385+}
1386+
1387+static void mt7531_eee_setting(struct dsa_switch *ds, u32 port)
1388+{
1389+ u32 val;
1390+
1391+ /* Disable EEE */
1392+ tc_phy_write_dev_reg(ds, port, PHY_DEV07, PHY_DEV07_REG_03C, 0);
1393+
1394+ /* Disable generate signal to clear the scramble_lock when lpi mode */
1395+ val = tc_phy_read_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_189);
1396+ val &= ~DESCRAMBLER_CLEAR_EN;
1397+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_189, val);
1398+
1399+ /* Roll back EEE Slave Mode */
1400+ tc_phy_write_dev_reg(ds, port, 0x1e, 0x2d1, 0);
1401+ mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_08, 0x1b);
1402+ mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_0f, 0);
1403+ mt753x_tr_write(ds, port, DSP_CH, DSP_NOD, DSP_10, 0x5000);
1404+
1405+ /* Adjust 100_mse_threshold */
1406+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_123, 0xffff);
1407+
1408+ /* Disable mcc */
1409+ tc_phy_write_dev_reg(ds, port, PHY_DEV1E, PHY_DEV1E_REG_A6, 0x300);
1410+}
1411+
1412+int mt7531_phy_setup(struct dsa_switch *ds)
1413+{
1414+ int ret;
1415+ int i;
1416+
1417+ mt7531_phy_setting(ds);
1418+
1419+ for (i = 0; i < MT7531_NUM_PHYS; i++) {
1420+ mt7531_adjust_line_driving(ds, i);
1421+ mt7531_eee_setting(ds, i);
1422+ }
1423+
1424+ /*for (i = 0; i < MT7531_NUM_PHYS; i++) {
1425+ ret = phy_calibration(ds, i);
1426+
1427+ rx_dc_offset(ds, i);
1428+ check_rx_dc_offset_pair_a(ds, i);
1429+ check_rx_dc_offset_pair_b(ds, i);
1430+ check_rx_dc_offset_pair_c(ds, i);
1431+ check_rx_dc_offset_pair_d(ds, i);
1432+
1433+ switch_phy_write(ds, i, 0, 0x1040);
1434+ }*/
1435+
1436+ return ret;
1437+}
developer5d148cb2023-06-02 13:08:11 +08001438diff --git a/drivers/net/dsa/mt7531_phy.h b/drivers/net/dsa/mt7531_phy.h
1439new file mode 100644
1440index 000000000..4cacabf54
developer24091172021-07-06 16:36:48 +08001441--- /dev/null
developer5d148cb2023-06-02 13:08:11 +08001442+++ b/drivers/net/dsa/mt7531_phy.h
developer24091172021-07-06 16:36:48 +08001443@@ -0,0 +1,262 @@
1444+/* SPDX-License-Identifier: GPL-2.0+ */
1445+/*
1446+ * Register definitions for MediaTek MT753x Gigabit switches
1447+ *
1448+ * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
1449+ *
1450+ * Author: Weijie Gao <weijie.gao@mediatek.com>
1451+ */
1452+
1453+#ifndef _MT753X_PHY_H_
1454+#define _MT753X_PHY_H_
1455+
1456+#include <linux/bitops.h>
1457+
1458+/*phy calibration use*/
1459+#define DEV_1E 0x1E
1460+/*global device 0x1f, always set P0*/
1461+#define DEV_1F 0x1F
1462+
1463+
1464+/************IEXT/REXT CAL***************/
1465+/* bits range: for example BITS(16,23) = 0xFF0000*/
1466+#define BITS(m, n) (~(BIT(m) - 1) & ((BIT(n) - 1) | BIT(n)))
1467+#define ANACAL_INIT 0x01
1468+#define ANACAL_ERROR 0xFD
1469+#define ANACAL_SATURATION 0xFE
1470+#define ANACAL_FINISH 0xFF
1471+#define ANACAL_PAIR_A 0
1472+#define ANACAL_PAIR_B 1
1473+#define ANACAL_PAIR_C 2
1474+#define ANACAL_PAIR_D 3
1475+#define DAC_IN_0V 0x00
1476+#define DAC_IN_2V 0xf0
1477+#define TX_AMP_OFFSET_0MV 0x20
1478+#define TX_AMP_OFFSET_VALID_BITS 6
1479+
1480+#define R0 0
1481+#define PHY0 0
1482+#define PHY1 1
1483+#define PHY2 2
1484+#define PHY3 3
1485+#define PHY4 4
1486+#define ANA_TEST_MODE BITS(8, 15)
1487+#define TST_TCLK_SEL BITs(6, 7)
1488+#define ANA_TEST_VGA_RG 0x100
1489+
1490+#define FORCE_MDI_CROSS_OVER BITS(3, 4)
1491+#define T10_TEST_CTL_RG 0x145
1492+#define RG_185 0x185
1493+#define RG_TX_SLEW BIT(0)
1494+#define ANA_CAL_0 0xdb
1495+#define RG_CAL_CKINV BIT(12)
1496+#define RG_ANA_CALEN BIT(8)
1497+#define RG_REXT_CALEN BIT(4)
1498+#define RG_ZCALEN_A BIT(0)
1499+#define ANA_CAL_1 0xdc
1500+#define RG_ZCALEN_B BIT(12)
1501+#define RG_ZCALEN_C BIT(8)
1502+#define RG_ZCALEN_D BIT(4)
1503+#define RG_TXVOS_CALEN BIT(0)
1504+#define ANA_CAL_6 0xe1
1505+#define RG_CAL_REFSEL BIT(4)
1506+#define RG_CAL_COMP_PWD BIT(0)
1507+#define ANA_CAL_5 0xe0
1508+#define RG_REXT_TRIM BITs(8, 13)
1509+#define RG_ZCAL_CTRL BITs(0, 5)
1510+#define RG_17A 0x17a
1511+#define AD_CAL_COMP_OUT BIT(8)
1512+#define RG_17B 0x17b
1513+#define AD_CAL_CLK bit(0)
1514+#define RG_17C 0x17c
1515+#define DA_CALIN_FLAG bit(0)
1516+/************R50 CAL****************************/
1517+#define RG_174 0x174
1518+#define RG_R50OHM_RSEL_TX_A_EN BIT[15]
1519+#define CR_R50OHM_RSEL_TX_A BITS[8:14]
1520+#define RG_R50OHM_RSEL_TX_B_EN BIT[7]
1521+#define CR_R50OHM_RSEL_TX_B BITS[6:0]
1522+#define RG_175 0x175
1523+#define RG_R50OHM_RSEL_TX_C_EN BITS[15]
1524+#define CR_R50OHM_RSEL_TX_C BITS[8:14]
1525+#define RG_R50OHM_RSEL_TX_D_EN BIT[7]
1526+#define CR_R50OHM_RSEL_TX_D BITS[0:6]
1527+/**********TX offset Calibration***************************/
1528+#define RG_95 0x96
1529+#define BYPASS_TX_OFFSET_CAL BIT(15)
1530+#define RG_3E 0x3e
1531+#define BYPASS_PD_TXVLD_A BIT(15)
1532+#define BYPASS_PD_TXVLD_B BIT(14)
1533+#define BYPASS_PD_TXVLD_C BIT(13)
1534+#define BYPASS_PD_TXVLD_D BIT(12)
1535+#define BYPASS_PD_TX_10M BIT(11)
1536+#define POWER_DOWN_TXVLD_A BIT(7)
1537+#define POWER_DOWN_TXVLD_B BIT(6)
1538+#define POWER_DOWN_TXVLD_C BIT(5)
1539+#define POWER_DOWN_TXVLD_D BIT(4)
1540+#define POWER_DOWN_TX_10M BIT(3)
1541+#define RG_DD 0xdd
1542+#define RG_TXG_CALEN_A BIT(12)
1543+#define RG_TXG_CALEN_B BIT(8)
1544+#define RG_TXG_CALEN_C BIT(4)
1545+#define RG_TXG_CALEN_D BIT(0)
1546+#define RG_17D 0x17D
1547+#define FORCE_DASN_DAC_IN0_A BIT(15)
1548+#define DASN_DAC_IN0_A BITS(0, 9)
1549+#define RG_17E 0x17E
1550+#define FORCE_DASN_DAC_IN0_B BIT(15)
1551+#define DASN_DAC_IN0_B BITS(0, 9)
1552+#define RG_17F 0x17F
1553+
1554+#define FORCE_DASN_DAC_IN0_C BIT(15)
1555+#define DASN_DAC_IN0_C BITS(0, 9)
1556+#define RG_180 0x180
1557+#define FORCE_DASN_DAC_IN0_D BIT(15)
1558+#define DASN_DAC_IN0_D BITS(0, 9)
1559+
1560+#define RG_181 0x181
1561+#define FORCE_DASN_DAC_IN1_A BIT(15)
1562+#define DASN_DAC_IN1_A BITS(0, 9)
1563+#define RG_182 0x182
1564+#define FORCE_DASN_DAC_IN1_B BIT(15)
1565+#define DASN_DAC_IN1_B BITS(0, 9)
1566+#define RG_183 0x183
1567+#define FORCE_DASN_DAC_IN1_C BIT(15)
1568+#define DASN_DAC_IN1_C BITS(0, 9)
1569+#define RG_184 0x184
1570+#define FORCE_DASN_DAC_IN1_D BIT(15)
1571+#define DASN_DAC_IN1_D BITS(0, 9)
1572+#define RG_172 0x172
1573+#define CR_TX_AMP_OFFSET_A BITS(8, 13)
1574+#define CR_TX_AMP_OFFSET_B BITS(0, 5)
1575+#define RG_173 0x173
1576+#define CR_TX_AMP_OFFSET_C BITS(8, 13)
1577+#define CR_TX_AMP_OFFSET_D BITS(0, 5)
1578+/**********TX Amp Calibration ***************************/
1579+#define RG_12 0x12
1580+#define DA_TX_I2MPB_A_GBE BITS(10, 15)
1581+#define RG_17 0x17
1582+#define DA_TX_I2MPB_B_GBE BITS(8, 13)
1583+#define RG_19 0x19
1584+#define DA_TX_I2MPB_C_GBE BITS(8, 13)
1585+#define RG_21 0x21
1586+#define DA_TX_I2MPB_D_GBE BITS(8, 13)
1587+#define TX_AMP_MAX 0x3f
1588+#define TX_AMP_MAX_OFFSET 0xb
1589+#define TX_AMP_HIGHEST_TS ((TX_AMP_MAX) + 3)
1590+#define TX_AMP_LOWEST_TS (0 - 3)
1591+#define TX_AMP_HIGH_TS (TX_AMP_MAX)
1592+#define TX_AMP_LOW_TS 0
1593+
1594+/* PHY Extend Register 0x14 bitmap of define */
1595+#define PHY_EXT_REG_14 0x14
1596+
1597+/* Fields of PHY_EXT_REG_14 */
1598+#define PHY_EN_DOWN_SHFIT BIT(4)
1599+
1600+/* PHY Extend Register 0x17 bitmap of define */
1601+#define PHY_EXT_REG_17 0x17
1602+
1603+/* Fields of PHY_EXT_REG_17 */
1604+#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
1605+
1606+/* PHY PMA Register 0x17 bitmap of define */
1607+#define SLV_DSP_READY_TIME_S 15
1608+#define SLV_DSP_READY_TIME_M (0xff << SLV_DSP_READY_TIME_S)
1609+
1610+/* PHY PMA Register 0x18 bitmap of define */
1611+#define ENABLE_RANDOM_UPDATE_TRIGGER BIT(8)
1612+
1613+/* PHY EEE Register bitmap of define */
1614+#define PHY_DEV07 0x07
1615+#define PHY_DEV07_REG_03C 0x3c
1616+
1617+/* PHY DEV 0x1e Register bitmap of define */
1618+#define PHY_DEV1E 0x1e
1619+#define PHY_DEV1F 0x1f
1620+
1621+/* Proprietory Control Register of Internal Phy device 0x1e */
1622+#define PHY_TX_MLT3_BASE 0x0
1623+#define PHY_DEV1E_REG_13 0x13
1624+#define PHY_DEV1E_REG_14 0x14
1625+#define PHY_DEV1E_REG_41 0x41
1626+#define PHY_DEV1E_REG_A6 0xa6
1627+#define RXADC_CONTROL_3 0xc2
1628+#define PHY_DEV1E_REG_0C6 0xc6
1629+#define RXADC_LDO_CONTROL_2 0xd3
1630+#define PHY_DEV1E_REG_0FE 0xfe
1631+#define PHY_DEV1E_REG_123 0x123
1632+#define PHY_DEV1E_REG_189 0x189
1633+#define PHY_DEV1E_REG_234 0x234
1634+
1635+/* Proprietory Control Register of Internal Phy device 0x1f */
1636+#define PHY_DEV1F_REG_44 0x44
1637+#define PHY_DEV1F_REG_268 0x268
1638+#define PHY_DEV1F_REG_269 0x269
1639+#define PHY_DEV1F_REG_26A 0x26A
1640+#define TXVLD_DA_271 0x271
1641+#define TXVLD_DA_272 0x272
1642+#define TXVLD_DA_273 0x273
1643+
1644+/* Fields of PHY_DEV1E_REG_0C6 */
1645+#define PHY_POWER_SAVING_S 8
1646+#define PHY_POWER_SAVING_M 0x300
1647+#define PHY_POWER_SAVING_TX 0x0
1648+
1649+/* Fields of PHY_DEV1E_REG_189 */
1650+#define DESCRAMBLER_CLEAR_EN 0x1
1651+
1652+/* Fields of PHY_DEV1E_REG_234 */
1653+#define TR_OPEN_LOOP_EN BIT(0)
1654+
1655+/* Internal GPHY Page Control Register */
1656+#define PHY_CL22_PAGE_CTRL 0x1f
1657+#define PHY_TR_PAGE 0x52b5
1658+
1659+/* Internal GPHY Token Ring Access Registers */
1660+#define PHY_TR_CTRL 0x10
1661+#define PHY_TR_LOW_DATA 0x11
1662+#define PHY_TR_HIGH_DATA 0x12
1663+
1664+/* Fields of PHY_TR_CTRL */
1665+#define PHY_TR_PKT_XMT_STA BIT(15)
1666+#define PHY_TR_WR_S 13
1667+#define PHY_TR_CH_ADDR_S 11
1668+#define PHY_TR_NODE_ADDR_S 7
1669+#define PHY_TR_DATA_ADDR_S 1
1670+
1671+enum phy_tr_wr {
1672+ PHY_TR_WRITE = 0,
1673+ PHY_TR_READ = 1,
1674+};
1675+
1676+/* Helper macro for GPHY Token Ring Access */
1677+#define PHY_TR_LOW_VAL(x) ((x) & 0xffff)
1678+#define PHY_TR_HIGH_VAL(x) (((x) & 0xff0000) >> 16)
1679+
1680+/* Token Ring Channels */
1681+#define PMA_CH 0x1
1682+#define DSP_CH 0x2
1683+
1684+/* Token Ring Nodes */
1685+#define PMA_NOD 0xf
1686+#define DSP_NOD 0xd
1687+
1688+/* Token Ring register range */
1689+enum tr_pma_reg_addr {
1690+ PMA_MIN = 0x0,
1691+ PMA_01 = 0x1,
1692+ PMA_17 = 0x17,
1693+ PMA_18 = 0x18,
1694+ PMA_MAX = 0x3d,
1695+};
1696+
1697+enum tr_dsp_reg_addr {
1698+ DSP_MIN = 0x0,
1699+ DSP_06 = 0x6,
1700+ DSP_08 = 0x8,
1701+ DSP_0f = 0xf,
1702+ DSP_10 = 0x10,
1703+ DSP_MAX = 0x3e,
1704+};
1705+#endif /* _MT753X_REGS_H_ */
developer5d148cb2023-06-02 13:08:11 +08001706--
17072.34.1
1708