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