Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: mediatek-ge-soc: sync driver with MediaTek SDK

Sync initialization and calibration routines with MediaTek's reference
driver. Improves compliance and resolves link stability issues with
CH340 IoT devices connected to MT798x built-in PHYs.

Fixes: 98c485eaf509 ("net: phy: add driver for MediaTek SoC built-in GE PHYs")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Link: https://lore.kernel.org/r/f2195279c234c0f618946424b8236026126bc595.1706071311.git.daniel@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Daniel Golle and committed by
Jakub Kicinski
ff63cc2e cae1f1c3

+81 -66
+81 -66
drivers/net/phy/mediatek-ge-soc.c
··· 489 489 u16 reg, val; 490 490 491 491 if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) 492 - bias = -2; 492 + bias = -1; 493 493 494 494 val = clamp_val(bias + tx_r50_cal_val, 0, 63); 495 495 ··· 705 705 static void mt798x_phy_common_finetune(struct phy_device *phydev) 706 706 { 707 707 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 708 + /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ 709 + __phy_write(phydev, 0x11, 0xc71); 710 + __phy_write(phydev, 0x12, 0xc); 711 + __phy_write(phydev, 0x10, 0x8fae); 712 + 708 713 /* EnabRandUpdTrig = 1 */ 709 714 __phy_write(phydev, 0x11, 0x2f00); 710 715 __phy_write(phydev, 0x12, 0xe); ··· 720 715 __phy_write(phydev, 0x12, 0x0); 721 716 __phy_write(phydev, 0x10, 0x83aa); 722 717 723 - /* TrFreeze = 0 */ 718 + /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ 719 + __phy_write(phydev, 0x11, 0x240); 720 + __phy_write(phydev, 0x12, 0x0); 721 + __phy_write(phydev, 0x10, 0x9680); 722 + 723 + /* TrFreeze = 0 (mt7988 default) */ 724 724 __phy_write(phydev, 0x11, 0x0); 725 725 __phy_write(phydev, 0x12, 0x0); 726 726 __phy_write(phydev, 0x10, 0x9686); 727 727 728 + /* SSTrKp100 = 5 */ 729 + /* SSTrKf100 = 6 */ 730 + /* SSTrKp1000Mas = 5 */ 731 + /* SSTrKf1000Mas = 6 */ 728 732 /* SSTrKp1000Slv = 5 */ 733 + /* SSTrKf1000Slv = 6 */ 729 734 __phy_write(phydev, 0x11, 0xbaef); 730 735 __phy_write(phydev, 0x12, 0x2e); 731 736 __phy_write(phydev, 0x10, 0x968c); 737 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 738 + } 739 + 740 + static void mt7981_phy_finetune(struct phy_device *phydev) 741 + { 742 + u16 val[8] = { 0x01ce, 0x01c1, 743 + 0x020f, 0x0202, 744 + 0x03d0, 0x03c0, 745 + 0x0013, 0x0005 }; 746 + int i, k; 747 + 748 + /* 100M eye finetune: 749 + * Keep middle level of TX MLT3 shapper as default. 750 + * Only change TX MLT3 overshoot level here. 751 + */ 752 + for (k = 0, i = 1; i < 12; i++) { 753 + if (i % 3 == 0) 754 + continue; 755 + phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); 756 + } 757 + 758 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 759 + /* ResetSyncOffset = 6 */ 760 + __phy_write(phydev, 0x11, 0x600); 761 + __phy_write(phydev, 0x12, 0x0); 762 + __phy_write(phydev, 0x10, 0x8fc0); 763 + 764 + /* VgaDecRate = 1 */ 765 + __phy_write(phydev, 0x11, 0x4c2a); 766 + __phy_write(phydev, 0x12, 0x3e); 767 + __phy_write(phydev, 0x10, 0x8fa4); 732 768 733 769 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, 734 770 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 ··· 784 738 __phy_write(phydev, 0x10, 0x8ec0); 785 739 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 786 740 787 - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ 741 + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ 788 742 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, 789 743 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, 790 744 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); ··· 817 771 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); 818 772 } 819 773 820 - static void mt7981_phy_finetune(struct phy_device *phydev) 821 - { 822 - u16 val[8] = { 0x01ce, 0x01c1, 823 - 0x020f, 0x0202, 824 - 0x03d0, 0x03c0, 825 - 0x0013, 0x0005 }; 826 - int i, k; 827 - 828 - /* 100M eye finetune: 829 - * Keep middle level of TX MLT3 shapper as default. 830 - * Only change TX MLT3 overshoot level here. 831 - */ 832 - for (k = 0, i = 1; i < 12; i++) { 833 - if (i % 3 == 0) 834 - continue; 835 - phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); 836 - } 837 - 838 - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 839 - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ 840 - __phy_write(phydev, 0x11, 0xc71); 841 - __phy_write(phydev, 0x12, 0xc); 842 - __phy_write(phydev, 0x10, 0x8fae); 843 - 844 - /* ResetSyncOffset = 6 */ 845 - __phy_write(phydev, 0x11, 0x600); 846 - __phy_write(phydev, 0x12, 0x0); 847 - __phy_write(phydev, 0x10, 0x8fc0); 848 - 849 - /* VgaDecRate = 1 */ 850 - __phy_write(phydev, 0x11, 0x4c2a); 851 - __phy_write(phydev, 0x12, 0x3e); 852 - __phy_write(phydev, 0x10, 0x8fa4); 853 - 854 - /* FfeUpdGainForce = 4 */ 855 - __phy_write(phydev, 0x11, 0x240); 856 - __phy_write(phydev, 0x12, 0x0); 857 - __phy_write(phydev, 0x10, 0x9680); 858 - 859 - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 860 - } 861 - 862 774 static void mt7988_phy_finetune(struct phy_device *phydev) 863 775 { 864 776 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, ··· 831 827 /* TCT finetune */ 832 828 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); 833 829 834 - /* Disable TX power saving */ 835 - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, 836 - MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); 837 - 838 830 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 839 - 840 - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ 841 - __phy_write(phydev, 0x11, 0x671); 842 - __phy_write(phydev, 0x12, 0xc); 843 - __phy_write(phydev, 0x10, 0x8fae); 844 - 845 831 /* ResetSyncOffset = 5 */ 846 832 __phy_write(phydev, 0x11, 0x500); 847 833 __phy_write(phydev, 0x12, 0x0); ··· 839 845 840 846 /* VgaDecRate is 1 at default on mt7988 */ 841 847 848 + /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, 849 + * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 850 + */ 851 + __phy_write(phydev, 0x11, 0xb90a); 852 + __phy_write(phydev, 0x12, 0x6f); 853 + __phy_write(phydev, 0x10, 0x8f82); 854 + 855 + /* RemAckCntLimitCtrl = 1 */ 856 + __phy_write(phydev, 0x11, 0xfbba); 857 + __phy_write(phydev, 0x12, 0xc3); 858 + __phy_write(phydev, 0x10, 0x87f8); 859 + 842 860 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 843 861 844 - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); 845 - /* TxClkOffset = 2 */ 846 - __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, 847 - FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); 848 - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 862 + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ 863 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, 864 + MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, 865 + BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); 866 + 867 + /* rg_tr_lpf_cnt_val = 1023 */ 868 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); 849 869 } 850 870 851 871 static void mt798x_phy_eee(struct phy_device *phydev) ··· 892 884 MTK_PHY_LPI_SLV_SEND_TX_EN, 893 885 FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); 894 886 895 - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, 896 - MTK_PHY_LPI_SEND_LOC_TIMER_MASK | 897 - MTK_PHY_LPI_TXPCS_LOC_RCV, 898 - FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); 887 + /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ 888 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, 889 + MTK_PHY_LPI_TXPCS_LOC_RCV); 899 890 891 + /* This also fixes some IoT issues, such as CH340 */ 900 892 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, 901 893 MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, 902 894 FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | ··· 930 922 __phy_write(phydev, 0x12, 0x0); 931 923 __phy_write(phydev, 0x10, 0x9690); 932 924 933 - /* REG_EEE_st2TrKf1000 = 3 */ 925 + /* REG_EEE_st2TrKf1000 = 2 */ 934 926 __phy_write(phydev, 0x11, 0x114f); 935 927 __phy_write(phydev, 0x12, 0x2); 936 928 __phy_write(phydev, 0x10, 0x969a); ··· 955 947 __phy_write(phydev, 0x12, 0x0); 956 948 __phy_write(phydev, 0x10, 0x96b8); 957 949 958 - /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ 950 + /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ 959 951 __phy_write(phydev, 0x11, 0x1463); 960 952 __phy_write(phydev, 0x12, 0x0); 961 953 __phy_write(phydev, 0x10, 0x96ca); ··· 1466 1458 err = mt7988_phy_fix_leds_polarities(phydev); 1467 1459 if (err) 1468 1460 return err; 1461 + 1462 + /* Disable TX power saving at probing to: 1463 + * 1. Meet common mode compliance test criteria 1464 + * 2. Make sure that TX-VCM calibration works fine 1465 + */ 1466 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, 1467 + MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); 1469 1468 1470 1469 return mt798x_phy_calibration(phydev); 1471 1470 }