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

net: mtk_eth_soc: convert code structure to suit split PCS support

Provide a mtk_pcs structure which encapsulates everything that the PCS
functions need (the regmap and ana_rgc3 offset), and use this in the
PCS functions. Provide shim functions to convert from the existing
"mtk_sgmii_*" interface to the converted PCS functions.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Russell King (Oracle) and committed by
Jakub Kicinski
901f3fbe 21089867

+83 -63
+12 -5
drivers/net/ethernet/mediatek/mtk_eth_soc.h
··· 869 869 /* currently no SoC has more than 2 macs */ 870 870 #define MTK_MAX_DEVS 2 871 871 872 - /* struct mtk_sgmii - This is the structure holding sgmii regmap and its 873 - * characteristics 872 + /* struct mtk_pcs - This structure holds each sgmii regmap and associated 873 + * data 874 874 * @regmap: The register map pointing at the range used to setup 875 875 * SGMII modes 876 876 * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap 877 877 */ 878 - 879 - struct mtk_sgmii { 880 - struct regmap *regmap[MTK_MAX_DEVS]; 878 + struct mtk_pcs { 879 + struct regmap *regmap; 881 880 u32 ana_rgc3; 881 + }; 882 + 883 + /* struct mtk_sgmii - This is the structure holding sgmii regmap and its 884 + * characteristics 885 + * @pcs Array of individual PCS structures 886 + */ 887 + struct mtk_sgmii { 888 + struct mtk_pcs pcs[MTK_MAX_DEVS]; 882 889 }; 883 890 884 891 /* struct mtk_eth - This is the main datasructure for holding the state
+71 -58
drivers/net/ethernet/mediatek/mtk_sgmii.c
··· 9 9 10 10 #include <linux/mfd/syscon.h> 11 11 #include <linux/of.h> 12 + #include <linux/phylink.h> 12 13 #include <linux/regmap.h> 13 14 14 15 #include "mtk_eth_soc.h" 15 16 16 - int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) 17 - { 18 - struct device_node *np; 19 - int i; 20 - 21 - ss->ana_rgc3 = ana_rgc3; 22 - 23 - for (i = 0; i < MTK_MAX_DEVS; i++) { 24 - np = of_parse_phandle(r, "mediatek,sgmiisys", i); 25 - if (!np) 26 - break; 27 - 28 - ss->regmap[i] = syscon_node_to_regmap(np); 29 - of_node_put(np); 30 - if (IS_ERR(ss->regmap[i])) 31 - return PTR_ERR(ss->regmap[i]); 32 - } 33 - 34 - return 0; 35 - } 36 - 37 17 /* For SGMII interface mode */ 38 - static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) 18 + static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) 39 19 { 40 20 unsigned int val; 41 21 42 - if (!ss->regmap[id]) 22 + if (!mpcs->regmap) 43 23 return -EINVAL; 44 24 45 25 /* Setup the link timer and QPHY power up inside SGMIISYS */ 46 - regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER, 26 + regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, 47 27 SGMII_LINK_TIMER_DEFAULT); 48 28 49 - regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); 29 + regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); 50 30 val |= SGMII_REMOTE_FAULT_DIS; 51 - regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); 31 + regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); 52 32 53 - regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); 33 + regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); 54 34 val |= SGMII_AN_RESTART; 55 - regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); 35 + regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); 56 36 57 - regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); 37 + regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); 58 38 val &= ~SGMII_PHYA_PWD; 59 - regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); 39 + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); 60 40 61 41 return 0; 42 + 62 43 } 63 44 64 45 /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a 65 46 * fixed speed. 66 47 */ 67 - static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, 68 - phy_interface_t interface) 48 + static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, 49 + phy_interface_t interface) 69 50 { 70 51 unsigned int val; 71 52 72 - if (!ss->regmap[id]) 53 + if (!mpcs->regmap) 73 54 return -EINVAL; 74 55 75 - regmap_read(ss->regmap[id], ss->ana_rgc3, &val); 56 + regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); 76 57 val &= ~RG_PHY_SPEED_MASK; 77 58 if (interface == PHY_INTERFACE_MODE_2500BASEX) 78 59 val |= RG_PHY_SPEED_3_125G; 79 - regmap_write(ss->regmap[id], ss->ana_rgc3, val); 60 + regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); 80 61 81 62 /* Disable SGMII AN */ 82 - regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); 63 + regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); 83 64 val &= ~SGMII_AN_ENABLE; 84 - regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); 65 + regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); 85 66 86 67 /* Set the speed etc but leave the duplex unchanged */ 87 - regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); 68 + regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); 88 69 val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; 89 70 val |= SGMII_SPEED_1000; 90 - regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); 71 + regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); 91 72 92 73 /* Release PHYA power down state */ 93 - regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); 74 + regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); 94 75 val &= ~SGMII_PHYA_PWD; 95 - regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); 76 + regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); 96 77 97 78 return 0; 98 79 } ··· 81 100 int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, 82 101 phy_interface_t interface) 83 102 { 103 + struct mtk_pcs *mpcs = &ss->pcs[id]; 84 104 int err = 0; 85 105 86 106 /* Setup SGMIISYS with the determined property */ 87 107 if (interface != PHY_INTERFACE_MODE_SGMII) 88 - err = mtk_sgmii_setup_mode_force(ss, id, interface); 108 + err = mtk_pcs_setup_mode_force(mpcs, interface); 89 109 else if (phylink_autoneg_inband(mode)) 90 - err = mtk_sgmii_setup_mode_an(ss, id); 110 + err = mtk_pcs_setup_mode_an(mpcs); 91 111 92 112 return err; 113 + } 114 + 115 + static void mtk_pcs_restart_an(struct mtk_pcs *mpcs) 116 + { 117 + unsigned int val; 118 + 119 + if (!mpcs->regmap) 120 + return; 121 + 122 + regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); 123 + val |= SGMII_AN_RESTART; 124 + regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); 125 + } 126 + 127 + static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex) 128 + { 129 + unsigned int val; 130 + 131 + /* SGMII force duplex setting */ 132 + regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); 133 + val &= ~SGMII_DUPLEX_FULL; 134 + if (duplex == DUPLEX_FULL) 135 + val |= SGMII_DUPLEX_FULL; 136 + 137 + regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); 93 138 } 94 139 95 140 /* For 1000BASE-X and 2500BASE-X interface modes */ 96 141 void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) 97 142 { 98 - unsigned int val; 143 + mtk_pcs_link_up(&ss->pcs[id], speed, duplex); 144 + } 99 145 100 - /* SGMII force duplex setting */ 101 - regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); 102 - val &= ~SGMII_DUPLEX_FULL; 103 - if (duplex == DUPLEX_FULL) 104 - val |= SGMII_DUPLEX_FULL; 146 + int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) 147 + { 148 + struct device_node *np; 149 + int i; 105 150 106 - regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); 151 + for (i = 0; i < MTK_MAX_DEVS; i++) { 152 + np = of_parse_phandle(r, "mediatek,sgmiisys", i); 153 + if (!np) 154 + break; 155 + 156 + ss->pcs[i].ana_rgc3 = ana_rgc3; 157 + ss->pcs[i].regmap = syscon_node_to_regmap(np); 158 + of_node_put(np); 159 + if (IS_ERR(ss->pcs[i].regmap)) 160 + return PTR_ERR(ss->pcs[i].regmap); 161 + } 162 + 163 + return 0; 107 164 } 108 165 109 166 void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id) 110 167 { 111 - struct mtk_sgmii *ss = eth->sgmii; 112 - unsigned int val, sid; 168 + unsigned int sid; 113 169 114 170 /* Decide how GMAC and SGMIISYS be mapped */ 115 171 sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? 116 172 0 : mac_id; 117 173 118 - if (!ss->regmap[sid]) 119 - return; 120 - 121 - regmap_read(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, &val); 122 - val |= SGMII_AN_RESTART; 123 - regmap_write(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, val); 174 + mtk_pcs_restart_an(&eth->sgmii->pcs[sid]); 124 175 }