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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-stmmac-cleanup-transmit-clock-setting'

Russell King says:

====================
net: stmmac: cleanup transmit clock setting

A lot of stmmac platform code which sets the transmit clock is very
similar - they decode the speed to the clock rate (125, 25 or 2.5 MHz)
and then set a clock to that rate.

The DWMAC core appears to have a clock input for the transmit section
called clk_tx_i which requires this rate.

This series moves the code which sets this clock into the core stmmac
code.

Patch 1 adds a hook that platforms can use to configure the clock rate.
Patch 2 adds a generic implementation.
The remainder of the patches convert the glue code for various platforms
to use this new infrastructure.
====================

Link: https://patch.msgid.link/Z8AtX-wyPal1auVO@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+108 -90
+2 -8
drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
··· 30 30 31 31 struct reset_control *rst; 32 32 struct clk *clk_slave; 33 - struct clk *clk_tx; 34 33 35 34 struct gpio_desc *reset; 36 35 }; ··· 149 150 { 150 151 struct tegra_eqos *eqos = priv; 151 152 bool needs_calibration = false; 152 - long rate = 125000000; 153 153 u32 value; 154 154 int err; 155 155 ··· 159 161 fallthrough; 160 162 161 163 case SPEED_10: 162 - rate = rgmii_clock(speed); 163 164 break; 164 165 165 166 default: ··· 205 208 value &= ~AUTO_CAL_CONFIG_ENABLE; 206 209 writel(value, eqos->regs + AUTO_CAL_CONFIG); 207 210 } 208 - 209 - err = clk_set_rate(eqos->clk_tx, rate); 210 - if (err < 0) 211 - dev_err(eqos->dev, "failed to set TX rate: %d\n", err); 212 211 } 213 212 214 213 static int tegra_eqos_init(struct platform_device *pdev, void *priv) ··· 240 247 if (!is_of_node(dev->fwnode)) 241 248 goto bypass_clk_reset_gpio; 242 249 243 - eqos->clk_tx = dwc_eth_find_clk(plat_dat, "tx"); 250 + plat_dat->clk_tx_i = dwc_eth_find_clk(plat_dat, "tx"); 244 251 245 252 eqos->reset = devm_gpiod_get(&pdev->dev, "phy-reset", GPIOD_OUT_HIGH); 246 253 if (IS_ERR(eqos->reset)) { ··· 274 281 275 282 bypass_clk_reset_gpio: 276 283 plat_dat->fix_mac_speed = tegra_eqos_fix_speed; 284 + plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate; 277 285 plat_dat->init = tegra_eqos_init; 278 286 plat_dat->bsp_priv = eqos; 279 287 plat_dat->flags |= STMMAC_FLAG_SPH_DISABLE;
+19 -2
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
··· 192 192 /* nothing to do now */ 193 193 } 194 194 195 + static int imx_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 196 + phy_interface_t interface, int speed) 197 + { 198 + struct imx_priv_data *dwmac = bsp_priv; 199 + 200 + interface = dwmac->plat_dat->mac_interface; 201 + if (interface == PHY_INTERFACE_MODE_RMII || 202 + interface == PHY_INTERFACE_MODE_MII) 203 + return 0; 204 + 205 + return stmmac_set_clk_tx_rate(bsp_priv, clk_tx_i, interface, speed); 206 + } 207 + 195 208 static void imx_dwmac_fix_speed(void *priv, int speed, unsigned int mode) 196 209 { 197 210 struct plat_stmmacenet_data *plat_dat; ··· 371 358 plat_dat->init = imx_dwmac_init; 372 359 plat_dat->exit = imx_dwmac_exit; 373 360 plat_dat->clks_config = imx_dwmac_clks_config; 374 - plat_dat->fix_mac_speed = imx_dwmac_fix_speed; 375 361 plat_dat->bsp_priv = dwmac; 376 362 dwmac->plat_dat = plat_dat; 377 363 dwmac->base_addr = stmmac_res.addr; ··· 383 371 if (ret) 384 372 goto err_dwmac_init; 385 373 386 - if (dwmac->ops->fix_mac_speed) 374 + if (dwmac->ops->fix_mac_speed) { 387 375 plat_dat->fix_mac_speed = dwmac->ops->fix_mac_speed; 376 + } else if (!dwmac->ops->mac_rgmii_txclk_auto_adj) { 377 + plat_dat->clk_tx_i = dwmac->clk_tx; 378 + plat_dat->set_clk_tx_rate = imx_dwmac_set_clk_tx_rate; 379 + } 380 + 388 381 dwmac->plat_dat->fix_soc_reset = dwmac->ops->fix_soc_reset; 389 382 390 383 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+3 -21
drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
··· 22 22 }; 23 23 24 24 struct intel_dwmac_data { 25 - void (*fix_mac_speed)(void *priv, int speed, unsigned int mode); 26 25 unsigned long ptp_ref_clk_rate; 27 26 unsigned long tx_clk_rate; 28 27 bool tx_clk_en; 29 28 }; 30 29 31 - static void kmb_eth_fix_mac_speed(void *priv, int speed, unsigned int mode) 32 - { 33 - struct intel_dwmac *dwmac = priv; 34 - long rate; 35 - int ret; 36 - 37 - rate = rgmii_clock(speed); 38 - if (rate < 0) { 39 - dev_err(dwmac->dev, "Invalid speed\n"); 40 - return; 41 - } 42 - 43 - ret = clk_set_rate(dwmac->tx_clk, rate); 44 - if (ret) 45 - dev_err(dwmac->dev, "Failed to configure tx clock rate\n"); 46 - } 47 - 48 30 static const struct intel_dwmac_data kmb_data = { 49 - .fix_mac_speed = kmb_eth_fix_mac_speed, 50 31 .ptp_ref_clk_rate = 200000000, 51 32 .tx_clk_rate = 125000000, 52 33 .tx_clk_en = true, ··· 70 89 * platform_match(). 71 90 */ 72 91 dwmac->data = device_get_match_data(&pdev->dev); 73 - if (dwmac->data->fix_mac_speed) 74 - plat_dat->fix_mac_speed = dwmac->data->fix_mac_speed; 75 92 76 93 /* Enable TX clock */ 77 94 if (dwmac->data->tx_clk_en) { ··· 110 131 } 111 132 } 112 133 } 134 + 135 + plat_dat->clk_tx_i = dwmac->tx_clk; 136 + plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate; 113 137 114 138 plat_dat->bsp_priv = dwmac; 115 139 plat_dat->eee_usecs_rate = plat_dat->clk_ptp_rate;
+5 -4
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
··· 260 260 return PTR_ERR_OR_ZERO(gmac->qsgmii_csr); 261 261 } 262 262 263 - static void ipq806x_gmac_fix_mac_speed(void *priv, int speed, unsigned int mode) 263 + static int ipq806x_gmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 264 + phy_interface_t interface, int speed) 264 265 { 265 - struct ipq806x_gmac *gmac = priv; 266 + struct ipq806x_gmac *gmac = bsp_priv; 266 267 267 - ipq806x_gmac_set_speed(gmac, speed); 268 + return ipq806x_gmac_set_speed(gmac, speed); 268 269 } 269 270 270 271 static int ··· 479 478 480 479 plat_dat->has_gmac = true; 481 480 plat_dat->bsp_priv = gmac; 482 - plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed; 481 + plat_dat->set_clk_tx_rate = ipq806x_gmac_set_clk_tx_rate; 483 482 plat_dat->multicast_filter_bins = 0; 484 483 plat_dat->tx_fifo_size = 8192; 485 484 plat_dat->rx_fifo_size = 8192;
+6 -3
drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
··· 22 22 void __iomem *reg; 23 23 }; 24 24 25 - static void meson6_dwmac_fix_mac_speed(void *priv, int speed, unsigned int mode) 25 + static int meson6_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 26 + phy_interface_t interface, int speed) 26 27 { 27 - struct meson_dwmac *dwmac = priv; 28 + struct meson_dwmac *dwmac = bsp_priv; 28 29 unsigned int val; 29 30 30 31 val = readl(dwmac->reg); ··· 40 39 } 41 40 42 41 writel(val, dwmac->reg); 42 + 43 + return 0; 43 44 } 44 45 45 46 static int meson6_dwmac_probe(struct platform_device *pdev) ··· 68 65 return PTR_ERR(dwmac->reg); 69 66 70 67 plat_dat->bsp_priv = dwmac; 71 - plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed; 68 + plat_dat->set_clk_tx_rate = meson6_dwmac_set_clk_tx_rate; 72 69 73 70 return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 74 71 }
+7 -3
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
··· 1920 1920 gmac_clk_enable(gmac, false); 1921 1921 } 1922 1922 1923 - static void rk_fix_speed(void *priv, int speed, unsigned int mode) 1923 + static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i, 1924 + phy_interface_t interface, int speed) 1924 1925 { 1925 - struct rk_priv_data *bsp_priv = priv; 1926 + struct rk_priv_data *bsp_priv = bsp_priv_; 1926 1927 struct device *dev = &bsp_priv->pdev->dev; 1927 1928 1928 1929 switch (bsp_priv->phy_iface) { ··· 1941 1940 default: 1942 1941 dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 1943 1942 } 1943 + 1944 + return 0; 1944 1945 } 1945 1946 1946 1947 static int rk_gmac_probe(struct platform_device *pdev) ··· 1971 1968 */ 1972 1969 if (!plat_dat->has_gmac4) 1973 1970 plat_dat->has_gmac = true; 1974 - plat_dat->fix_mac_speed = rk_fix_speed; 1971 + 1972 + plat_dat->set_clk_tx_rate = rk_set_clk_tx_rate; 1975 1973 1976 1974 plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1977 1975 if (IS_ERR(plat_dat->bsp_priv))
+3 -19
drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
··· 100 100 clk_disable_unprepare(gmac->rx_clk); 101 101 } 102 102 103 - static void s32_fix_mac_speed(void *priv, int speed, unsigned int mode) 104 - { 105 - struct s32_priv_data *gmac = priv; 106 - long tx_clk_rate; 107 - int ret; 108 - 109 - tx_clk_rate = rgmii_clock(speed); 110 - if (tx_clk_rate < 0) { 111 - dev_err(gmac->dev, "Unsupported/Invalid speed: %d\n", speed); 112 - return; 113 - } 114 - 115 - dev_dbg(gmac->dev, "Set tx clock to %ld Hz\n", tx_clk_rate); 116 - ret = clk_set_rate(gmac->tx_clk, tx_clk_rate); 117 - if (ret) 118 - dev_err(gmac->dev, "Can't set tx clock\n"); 119 - } 120 - 121 103 static int s32_dwmac_probe(struct platform_device *pdev) 122 104 { 123 105 struct plat_stmmacenet_data *plat; ··· 154 172 155 173 plat->init = s32_gmac_init; 156 174 plat->exit = s32_gmac_exit; 157 - plat->fix_mac_speed = s32_fix_mac_speed; 175 + 176 + plat->clk_tx_i = gmac->tx_clk; 177 + plat->set_clk_tx_rate = stmmac_set_clk_tx_rate; 158 178 159 179 plat->bsp_priv = gmac; 160 180
+4 -22
drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
··· 27 27 28 28 struct starfive_dwmac { 29 29 struct device *dev; 30 - struct clk *clk_tx; 31 30 const struct starfive_dwmac_data *data; 32 31 }; 33 - 34 - static void starfive_dwmac_fix_mac_speed(void *priv, int speed, unsigned int mode) 35 - { 36 - struct starfive_dwmac *dwmac = priv; 37 - long rate; 38 - int err; 39 - 40 - rate = rgmii_clock(speed); 41 - if (rate < 0) { 42 - dev_err(dwmac->dev, "invalid speed %d\n", speed); 43 - return; 44 - } 45 - 46 - err = clk_set_rate(dwmac->clk_tx, rate); 47 - if (err) 48 - dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate); 49 - } 50 32 51 33 static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat) 52 34 { ··· 104 122 105 123 dwmac->data = device_get_match_data(&pdev->dev); 106 124 107 - dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx"); 108 - if (IS_ERR(dwmac->clk_tx)) 109 - return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx), 125 + plat_dat->clk_tx_i = devm_clk_get_enabled(&pdev->dev, "tx"); 126 + if (IS_ERR(plat_dat->clk_tx_i)) 127 + return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat->clk_tx_i), 110 128 "error getting tx clock\n"); 111 129 112 130 clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx"); ··· 121 139 * internally, because rgmii_rxin will be adaptively adjusted. 122 140 */ 123 141 if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk")) 124 - plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed; 142 + plat_dat->set_clk_tx_rate = stmmac_set_clk_tx_rate; 125 143 126 144 dwmac->dev = &pdev->dev; 127 145 plat_dat->bsp_priv = dwmac;
+10 -8
drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
··· 101 101 return 0; 102 102 } 103 103 104 - static void thead_dwmac_fix_speed(void *priv, int speed, unsigned int mode) 104 + static int thead_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 105 + phy_interface_t interface, int speed) 105 106 { 107 + struct thead_dwmac *dwmac = bsp_priv; 106 108 struct plat_stmmacenet_data *plat; 107 - struct thead_dwmac *dwmac = priv; 108 109 unsigned long rate; 109 110 long tx_rate; 110 111 u32 div, reg; ··· 115 114 switch (plat->mac_interface) { 116 115 /* For MII, rxc/txc is provided by phy */ 117 116 case PHY_INTERFACE_MODE_MII: 118 - return; 117 + return 0; 119 118 120 119 case PHY_INTERFACE_MODE_RGMII: 121 120 case PHY_INTERFACE_MODE_RGMII_ID: ··· 128 127 tx_rate = rgmii_clock(speed); 129 128 if (tx_rate < 0) { 130 129 dev_err(dwmac->dev, "invalid speed %d\n", speed); 131 - return; 130 + return tx_rate; 132 131 } 133 132 134 133 div = rate / tx_rate; 135 134 if (rate != tx_rate * div) { 136 135 dev_err(dwmac->dev, "invalid gmac rate %lu\n", rate); 137 - return; 136 + return -EINVAL; 138 137 } 139 138 140 139 reg = FIELD_PREP(GMAC_PLLCLK_DIV_EN, 1) | 141 140 FIELD_PREP(GMAC_PLLCLK_DIV_NUM, div); 142 141 writel(reg, dwmac->apb_base + GMAC_PLLCLK_DIV); 143 - break; 142 + return 0; 143 + 144 144 default: 145 145 dev_err(dwmac->dev, "unsupported phy interface %d\n", 146 146 plat->mac_interface); 147 - return; 147 + return -EINVAL; 148 148 } 149 149 } 150 150 ··· 237 235 dwmac->plat = plat; 238 236 dwmac->apb_base = apb; 239 237 plat->bsp_priv = dwmac; 240 - plat->fix_mac_speed = thead_dwmac_fix_speed; 238 + plat->set_clk_tx_rate = thead_set_clk_tx_rate; 241 239 plat->init = thead_dwmac_init; 242 240 243 241 return devm_stmmac_pltfr_probe(pdev, plat, &stmmac_res);
+2
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 407 407 int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt); 408 408 int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size); 409 409 int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled); 410 + int stmmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 411 + phy_interface_t interface, int speed); 410 412 411 413 static inline bool stmmac_xdp_is_enabled(struct stmmac_priv *priv) 412 414 {
+43
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 178 178 EXPORT_SYMBOL_GPL(stmmac_bus_clks_config); 179 179 180 180 /** 181 + * stmmac_set_clk_tx_rate() - set the clock rate for the MAC transmit clock 182 + * @bsp_priv: BSP private data structure (unused) 183 + * @clk_tx_i: the transmit clock 184 + * @interface: the selected interface mode 185 + * @speed: the speed that the MAC will be operating at 186 + * 187 + * Set the transmit clock rate for the MAC, normally 2.5MHz for 10Mbps, 188 + * 25MHz for 100Mbps and 125MHz for 1Gbps. This is suitable for at least 189 + * MII, GMII, RGMII and RMII interface modes. Platforms can hook this into 190 + * the plat_data->set_clk_tx_rate method directly, call it via their own 191 + * implementation, or implement their own method should they have more 192 + * complex requirements. It is intended to only be used in this method. 193 + * 194 + * plat_data->clk_tx_i must be filled in. 195 + */ 196 + int stmmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 197 + phy_interface_t interface, int speed) 198 + { 199 + long rate = rgmii_clock(speed); 200 + 201 + /* Silently ignore unsupported speeds as rgmii_clock() only 202 + * supports 10, 100 and 1000Mbps. We do not want to spit 203 + * errors for 2500 and higher speeds here. 204 + */ 205 + if (rate < 0) 206 + return 0; 207 + 208 + return clk_set_rate(clk_tx_i, rate); 209 + } 210 + EXPORT_SYMBOL_GPL(stmmac_set_clk_tx_rate); 211 + 212 + /** 181 213 * stmmac_verify_args - verify the driver parameters. 182 214 * Description: it checks the driver parameters and set a default in case of 183 215 * errors. ··· 960 928 struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); 961 929 unsigned int flow_ctrl; 962 930 u32 old_ctrl, ctrl; 931 + int ret; 963 932 964 933 if ((priv->plat->flags & STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP) && 965 934 priv->plat->serdes_powerup) ··· 1052 1019 1053 1020 if (ctrl != old_ctrl) 1054 1021 writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 1022 + 1023 + if (priv->plat->set_clk_tx_rate) { 1024 + ret = priv->plat->set_clk_tx_rate(priv->plat->bsp_priv, 1025 + priv->plat->clk_tx_i, 1026 + interface, speed); 1027 + if (ret < 0) 1028 + netdev_err(priv->dev, 1029 + "failed to configure transmit clock for %dMbps: %pe\n", 1030 + speed, ERR_PTR(ret)); 1031 + } 1055 1032 1056 1033 stmmac_mac_set(priv, priv->ioaddr, true); 1057 1034 if (priv->dma_cap.eee)
+4
include/linux/stmmac.h
··· 78 78 | DMA_AXI_BLEN_32 | DMA_AXI_BLEN_64 \ 79 79 | DMA_AXI_BLEN_128 | DMA_AXI_BLEN_256) 80 80 81 + struct clk; 81 82 struct stmmac_priv; 82 83 83 84 /* Platfrom data for platform device structure's platform_data field */ ··· 232 231 u8 tx_sched_algorithm; 233 232 struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES]; 234 233 struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; 234 + int (*set_clk_tx_rate)(void *priv, struct clk *clk_tx_i, 235 + phy_interface_t interface, int speed); 235 236 void (*fix_mac_speed)(void *priv, int speed, unsigned int mode); 236 237 int (*fix_soc_reset)(void *priv, void __iomem *ioaddr); 237 238 int (*serdes_powerup)(struct net_device *ndev, void *priv); ··· 255 252 struct clk *stmmac_clk; 256 253 struct clk *pclk; 257 254 struct clk *clk_ptp_ref; 255 + struct clk *clk_tx_i; /* clk_tx_i to MAC core */ 258 256 unsigned long clk_ptp_rate; 259 257 unsigned long clk_ref_rate; 260 258 struct clk_bulk_data *clks;