History

Merge branch 'dwmac-dwc-qos-eth'

Joao Pinto says: ==================== adding new glue driver dwmac-dwc-qos-eth This patch set contains the porting of the synopsys/dwc_eth_qos.c driver to the stmmac structure. This operation resulted in the creation of a new platform glue driver called dwmac-dwc-qos-eth which was based in the dwc_eth_qos as is. dwmac-dwc-qos-eth inherited dwc_eth_qos DT bindings, to assure that current and old users can continue to use it as before. We can see this driver as being deprecated, since all new development will be done in stmmac. Please check each patch for implementation details. ====================

David S. Miller committed 9 years ago

Commit 3b647be2 parents 3a7f75e d82561215 files · +317 −82Browse files

Unified · Split

15 files
  1. Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt +3 −0
  2. Documentation/devicetree/bindings/net/stmmac.txt +2 −0
  3. drivers/net/ethernet/stmicro/stmmac/Kconfig +9 −0
  4. drivers/net/ethernet/stmicro/stmmac/Makefile +1 −0
  5. drivers/net/ethernet/stmicro/stmmac/common.h +2 −1
  6. drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +202 −0
  7. drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +1 −1
  8. drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +4 −1
  9. drivers/net/ethernet/stmicro/stmmac/dwmac4.h +1 −0
  10. drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +5 −1
  11. drivers/net/ethernet/stmicro/stmmac/stmmac.h +0 −5
  12. drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +2 −2
  13. drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +17 −68
  14. drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +62 −3
  15. include/linux/stmmac.h +6 −0
Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt+3−0
@@ -1,5 +1,8 @@
1* Synopsys DWC Ethernet QoS IP version 4.10 driver (GMAC)1* Synopsys DWC Ethernet QoS IP version 4.10 driver (GMAC)
2 2
3This binding is deprecated, but it continues to be supported, but new
4features should be preferably added to the stmmac binding document.
5
3This binding supports the Synopsys Designware Ethernet QoS (Quality Of Service)6This binding supports the Synopsys Designware Ethernet QoS (Quality Of Service)
4IP block. The IP supports multiple options for bus type, clocking and reset7IP block. The IP supports multiple options for bus type, clocking and reset
5structure, and feature list. Consequently, a number of properties and list8structure, and feature list. Consequently, a number of properties and list
Documentation/devicetree/bindings/net/stmmac.txt+2−0
@@ -49,6 +49,8 @@ Optional properties: · 48 unmodified lines
49- snps,force_sf_dma_mode Force DMA to use the Store and Forward49- snps,force_sf_dma_mode Force DMA to use the Store and Forward
50 mode for both tx and rx. This flag is50 mode for both tx and rx. This flag is
51 ignored if force_thresh_dma_mode is set.51 ignored if force_thresh_dma_mode is set.
52- snps,en-tx-lpi-clockgating Enable gating of the MAC TX clock during
53 TX low-power mode
52- snps,multicast-filter-bins: Number of multicast filter hash bins54- snps,multicast-filter-bins: Number of multicast filter hash bins
53 supported by this device instance55 supported by this device instance
54- snps,perfect-filter-entries: Number of perfect filter entries supported56- snps,perfect-filter-entries: Number of perfect filter entries supported
drivers/net/ethernet/stmicro/stmmac/Kconfig+9−0
@@ -29,6 +29,15 @@ config STMMAC_PLATFORM · 28 unmodified lines
29 29
30if STMMAC_PLATFORM30if STMMAC_PLATFORM
31 31
32config DWMAC_DWC_QOS_ETH
33 tristate "Support for snps,dwc-qos-ethernet.txt DT binding."
34 select PHYLIB
35 select CRC32
36 select MII
37 depends on OF && HAS_DMA
38 help
39 Support for chips using the snps,dwc-qos-ethernet.txt DT binding.
40
32config DWMAC_GENERIC41config DWMAC_GENERIC
33 tristate "Generic driver for DWMAC"42 tristate "Generic driver for DWMAC"
34 default STMMAC_PLATFORM43 default STMMAC_PLATFORM
drivers/net/ethernet/stmicro/stmmac/Makefile+1−0
@@ -16,6 +16,7 @@ obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o · 15 unmodified lines
16obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o16obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
17obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o17obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
18obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o18obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
19obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o
19obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o20obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o
20stmmac-platform-objs:= stmmac_platform.o21stmmac-platform-objs:= stmmac_platform.o
21dwmac-altr-socfpga-objs := altr_tse_pcs.o dwmac-socfpga.o22dwmac-altr-socfpga-objs := altr_tse_pcs.o dwmac-socfpga.o
drivers/net/ethernet/stmicro/stmmac/common.h+2−1
@@ -476,7 +476,8 @@ struct stmmac_ops { · 475 unmodified lines
476 unsigned int reg_n);476 unsigned int reg_n);
477 void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,477 void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
478 unsigned int reg_n);478 unsigned int reg_n);
479 void (*set_eee_mode)(struct mac_device_info *hw);479 void (*set_eee_mode)(struct mac_device_info *hw,
480 bool en_tx_lpi_clockgating);
480 void (*reset_eee_mode)(struct mac_device_info *hw);481 void (*reset_eee_mode)(struct mac_device_info *hw);
481 void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);482 void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
482 void (*set_eee_pls)(struct mac_device_info *hw, int link);483 void (*set_eee_pls)(struct mac_device_info *hw, int link);
drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c+202−0
@@ -0,0 +1,202 @@
1/*
2 * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
3 *
4 * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * You should have received a copy of the GNU General Public License
11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */
13
14#include <linux/clk.h>
15#include <linux/clk-provider.h>
16#include <linux/device.h>
17#include <linux/ethtool.h>
18#include <linux/io.h>
19#include <linux/ioport.h>
20#include <linux/module.h>
21#include <linux/of_net.h>
22#include <linux/mfd/syscon.h>
23#include <linux/platform_device.h>
24#include <linux/stmmac.h>
25
26#include "stmmac_platform.h"
27
28static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
29 struct plat_stmmacenet_data *plat_dat)
30{
31 struct device_node *np = pdev->dev.of_node;
32 u32 burst_map = 0;
33 u32 bit_index = 0;
34 u32 a_index = 0;
35
36 if (!plat_dat->axi) {
37 plat_dat->axi = kzalloc(sizeof(struct stmmac_axi), GFP_KERNEL);
38
39 if (!plat_dat->axi)
40 return -ENOMEM;
41 }
42
43 plat_dat->axi->axi_lpi_en = of_property_read_bool(np, "snps,en-lpi");
44 if (of_property_read_u32(np, "snps,write-requests",
45 &plat_dat->axi->axi_wr_osr_lmt)) {
46 /**
47 * Since the register has a reset value of 1, if property
48 * is missing, default to 1.
49 */
50 plat_dat->axi->axi_wr_osr_lmt = 1;
51 } else {
52 /**
53 * If property exists, to keep the behavior from dwc_eth_qos,
54 * subtract one after parsing.
55 */
56 plat_dat->axi->axi_wr_osr_lmt--;
57 }
58
59 if (of_property_read_u32(np, "read,read-requests",
60 &plat_dat->axi->axi_rd_osr_lmt)) {
61 /**
62 * Since the register has a reset value of 1, if property
63 * is missing, default to 1.
64 */
65 plat_dat->axi->axi_rd_osr_lmt = 1;
66 } else {
67 /**
68 * If property exists, to keep the behavior from dwc_eth_qos,
69 * subtract one after parsing.
70 */
71 plat_dat->axi->axi_rd_osr_lmt--;
72 }
73 of_property_read_u32(np, "snps,burst-map", &burst_map);
74
75 /* converts burst-map bitmask to burst array */
76 for (bit_index = 0; bit_index < 7; bit_index++) {
77 if (burst_map & (1 << bit_index)) {
78 switch (bit_index) {
79 case 0:
80 plat_dat->axi->axi_blen[a_index] = 4; break;
81 case 1:
82 plat_dat->axi->axi_blen[a_index] = 8; break;
83 case 2:
84 plat_dat->axi->axi_blen[a_index] = 16; break;
85 case 3:
86 plat_dat->axi->axi_blen[a_index] = 32; break;
87 case 4:
88 plat_dat->axi->axi_blen[a_index] = 64; break;
89 case 5:
90 plat_dat->axi->axi_blen[a_index] = 128; break;
91 case 6:
92 plat_dat->axi->axi_blen[a_index] = 256; break;
93 default:
94 break;
95 }
96 a_index++;
97 }
98 }
99
100 /* dwc-qos needs GMAC4, AAL, TSO and PMT */
101 plat_dat->has_gmac4 = 1;
102 plat_dat->dma_cfg->aal = 1;
103 plat_dat->tso_en = 1;
104 plat_dat->pmt = 1;
105
106 return 0;
107}
108
109static int dwc_eth_dwmac_probe(struct platform_device *pdev)
110{
111 struct plat_stmmacenet_data *plat_dat;
112 struct stmmac_resources stmmac_res;
113 struct resource *res;
114 int ret;
115
116 memset(&stmmac_res, 0, sizeof(struct stmmac_resources));
117
118 /**
119 * Since stmmac_platform supports name IRQ only, basic platform
120 * resource initialization is done in the glue logic.
121 */
122 stmmac_res.irq = platform_get_irq(pdev, 0);
123 if (stmmac_res.irq < 0) {
124 if (stmmac_res.irq != -EPROBE_DEFER)
125 dev_err(&pdev->dev,
126 "IRQ configuration information not found\n");
127
128 return stmmac_res.irq;
129 }
130 stmmac_res.wol_irq = stmmac_res.irq;
131
132 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
133 stmmac_res.addr = devm_ioremap_resource(&pdev->dev, res);
134 if (IS_ERR(stmmac_res.addr))
135 return PTR_ERR(stmmac_res.addr);
136
137 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
138 if (IS_ERR(plat_dat))
139 return PTR_ERR(plat_dat);
140
141 plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk");
142 if (IS_ERR(plat_dat->stmmac_clk)) {
143 dev_err(&pdev->dev, "apb_pclk clock not found.\n");
144 ret = PTR_ERR(plat_dat->stmmac_clk);
145 plat_dat->stmmac_clk = NULL;
146 goto err_remove_config_dt;
147 }
148 clk_prepare_enable(plat_dat->stmmac_clk);
149
150 plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk");
151 if (IS_ERR(plat_dat->pclk)) {
152 dev_err(&pdev->dev, "phy_ref_clk clock not found.\n");
153 ret = PTR_ERR(plat_dat->pclk);
154 plat_dat->pclk = NULL;
155 goto err_out_clk_dis_phy;
156 }
157 clk_prepare_enable(plat_dat->pclk);
158
159 ret = dwc_eth_dwmac_config_dt(pdev, plat_dat);
160 if (ret)
161 goto err_out_clk_dis_aper;
162
163 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
164 if (ret)
165 goto err_out_clk_dis_aper;
166
167 return 0;
168
169err_out_clk_dis_aper:
170 clk_disable_unprepare(plat_dat->pclk);
171err_out_clk_dis_phy:
172 clk_disable_unprepare(plat_dat->stmmac_clk);
173err_remove_config_dt:
174 stmmac_remove_config_dt(pdev, plat_dat);
175
176 return ret;
177}
178
179static int dwc_eth_dwmac_remove(struct platform_device *pdev)
180{
181 return stmmac_pltfr_remove(pdev);
182}
183
184static const struct of_device_id dwc_eth_dwmac_match[] = {
185 { .compatible = "snps,dwc-qos-ethernet-4.10", },
186 { }
187};
188MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);
189
190static struct platform_driver dwc_eth_dwmac_driver = {
191 .probe = dwc_eth_dwmac_probe,
192 .remove = dwc_eth_dwmac_remove,
193 .driver = {
194 .name = "dwc-eth-dwmac",
195 .of_match_table = dwc_eth_dwmac_match,
196 },
197};
198module_platform_driver(dwc_eth_dwmac_driver);
199
200MODULE_AUTHOR("Joao Pinto <jpinto@synopsys.com>");
201MODULE_DESCRIPTION("Synopsys DWC Ethernet Quality-of-Service v4.10a driver");
202MODULE_LICENSE("GPL v2");
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c+1−1
@@ -341,7 +341,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) · 340 unmodified lines
341 * mode. Create a copy of the core reset handle so it can be used by341 * mode. Create a copy of the core reset handle so it can be used by
342 * the driver later.342 * the driver later.
343 */343 */
344 dwmac->stmmac_rst = stpriv->stmmac_rst;344 dwmac->stmmac_rst = stpriv->plat->stmmac_rst;
345 345
346 ret = socfpga_dwmac_set_phy_mode(dwmac);346 ret = socfpga_dwmac_set_phy_mode(dwmac);
347 if (ret)347 if (ret)
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c+4−1
@@ -343,11 +343,14 @@ static int dwmac1000_irq_status(struct mac_device_info *hw, · 342 unmodified lines
343 return ret;343 return ret;
344}344}
345 345
346static void dwmac1000_set_eee_mode(struct mac_device_info *hw)346static void dwmac1000_set_eee_mode(struct mac_device_info *hw,
347 bool en_tx_lpi_clockgating)
347{348{
348 void __iomem *ioaddr = hw->pcsr;349 void __iomem *ioaddr = hw->pcsr;
349 u32 value;350 u32 value;
350 351
352 /*TODO - en_tx_lpi_clockgating treatment */
353
351 /* Enable the link status receive on RGMII, SGMII ore SMII354 /* Enable the link status receive on RGMII, SGMII ore SMII
352 * receive path and instruct the transmit to enter in LPI355 * receive path and instruct the transmit to enter in LPI
353 * state.356 * state.
drivers/net/ethernet/stmicro/stmmac/dwmac4.h+1−0
@@ -98,6 +98,7 @@ enum power_event { · 97 unmodified lines
98#define GMAC4_LPI_TIMER_CTRL 0xd498#define GMAC4_LPI_TIMER_CTRL 0xd4
99 99
100/* LPI control and status defines */100/* LPI control and status defines */
101#define GMAC4_LPI_CTRL_STATUS_LPITCSE BIT(21) /* LPI Tx Clock Stop Enable */
101#define GMAC4_LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */102#define GMAC4_LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */
102#define GMAC4_LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */103#define GMAC4_LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */
103#define GMAC4_LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */104#define GMAC4_LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c+5−1
@@ -137,7 +137,8 @@ static void dwmac4_get_umac_addr(struct mac_device_info *hw, · 136 unmodified lines
137 GMAC_ADDR_LOW(reg_n));137 GMAC_ADDR_LOW(reg_n));
138}138}
139 139
140static void dwmac4_set_eee_mode(struct mac_device_info *hw)140static void dwmac4_set_eee_mode(struct mac_device_info *hw,
141 bool en_tx_lpi_clockgating)
141{142{
142 void __iomem *ioaddr = hw->pcsr;143 void __iomem *ioaddr = hw->pcsr;
143 u32 value;144 u32 value;
@@ -149,6 +150,9 @@ static void dwmac4_set_eee_mode(struct mac_device_info *hw) · 5 unmodified lines
149 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);150 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS);
150 value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA;151 value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA;
151 152
153 if (en_tx_lpi_clockgating)
154 value |= GMAC4_LPI_CTRL_STATUS_LPITCSE;
155
152 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);156 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS);
153}157}
154 158
drivers/net/ethernet/stmicro/stmmac/stmmac.h+0−5
@@ -106,9 +106,6 @@ struct stmmac_priv { · 105 unmodified lines
106 u32 msg_enable;106 u32 msg_enable;
107 int wolopts;107 int wolopts;
108 int wol_irq;108 int wol_irq;
109 struct clk *stmmac_clk;
110 struct clk *pclk;
111 struct reset_control *stmmac_rst;
112 int clk_csr;109 int clk_csr;
113 struct timer_list eee_ctrl_timer;110 struct timer_list eee_ctrl_timer;
114 int lpi_irq;111 int lpi_irq;
@@ -120,8 +117,6 @@ struct stmmac_priv { · 5 unmodified lines
120 struct ptp_clock *ptp_clock;117 struct ptp_clock *ptp_clock;
121 struct ptp_clock_info ptp_clock_ops;118 struct ptp_clock_info ptp_clock_ops;
122 unsigned int default_addend;119 unsigned int default_addend;
123 struct clk *clk_ptp_ref;
124 unsigned int clk_ptp_rate;
125 u32 adv_ts;120 u32 adv_ts;
126 int use_riwt;121 int use_riwt;
127 int irq_wake;122 int irq_wake;
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c+2−2
@@ -712,7 +712,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev, · 711 unmodified lines
712 712
713static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)713static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv)
714{714{
715 unsigned long clk = clk_get_rate(priv->stmmac_clk);715 unsigned long clk = clk_get_rate(priv->plat->stmmac_clk);
716 716
717 if (!clk)717 if (!clk)
718 return 0;718 return 0;
@@ -722,7 +722,7 @@ static u32 stmmac_usec2riwt(u32 usec, struct stmmac_priv *priv) · 3 unmodified lines
722 722
723static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv)723static u32 stmmac_riwt2usec(u32 riwt, struct stmmac_priv *priv)
724{724{
725 unsigned long clk = clk_get_rate(priv->stmmac_clk);725 unsigned long clk = clk_get_rate(priv->plat->stmmac_clk);
726 726
727 if (!clk)727 if (!clk)
728 return 0;728 return 0;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+17−68
@@ -158,7 +158,7 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv) · 157 unmodified lines
158{158{
159 u32 clk_rate;159 u32 clk_rate;
160 160
161 clk_rate = clk_get_rate(priv->stmmac_clk);161 clk_rate = clk_get_rate(priv->plat->stmmac_clk);
162 162
163 /* Platform provided default clk_csr would be assumed valid163 /* Platform provided default clk_csr would be assumed valid
164 * for all other cases except for the below mentioned ones.164 * for all other cases except for the below mentioned ones.
@@ -239,7 +239,8 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv) · 74 unmodified lines
239 /* Check and enter in LPI mode */239 /* Check and enter in LPI mode */
240 if ((priv->dirty_tx == priv->cur_tx) &&240 if ((priv->dirty_tx == priv->cur_tx) &&
241 (priv->tx_path_in_lpi_mode == false))241 (priv->tx_path_in_lpi_mode == false))
242 priv->hw->mac->set_eee_mode(priv->hw);242 priv->hw->mac->set_eee_mode(priv->hw,
243 priv->plat->en_tx_lpi_clockgating);
243}244}
244 245
245/**246/**
@@ -606,7 +607,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) · 360 unmodified lines
606 607
607 /* program Sub Second Increment reg */608 /* program Sub Second Increment reg */
608 sec_inc = priv->hw->ptp->config_sub_second_increment(609 sec_inc = priv->hw->ptp->config_sub_second_increment(
609 priv->ptpaddr, priv->clk_ptp_rate,610 priv->ptpaddr, priv->plat->clk_ptp_rate,
610 priv->plat->has_gmac4);611 priv->plat->has_gmac4);
611 temp = div_u64(1000000000ULL, sec_inc);612 temp = div_u64(1000000000ULL, sec_inc);
612 613
@@ -616,7 +617,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) · 3 unmodified lines
616 * where, freq_div_ratio = 1e9ns/sec_inc617 * where, freq_div_ratio = 1e9ns/sec_inc
617 */618 */
618 temp = (u64)(temp << 32);619 temp = (u64)(temp << 32);
619 priv->default_addend = div_u64(temp, priv->clk_ptp_rate);620 priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
620 priv->hw->ptp->config_addend(priv->ptpaddr,621 priv->hw->ptp->config_addend(priv->ptpaddr,
621 priv->default_addend);622 priv->default_addend);
622 623
@@ -644,18 +645,6 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) · 21 unmodified lines
644 if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))645 if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
645 return -EOPNOTSUPP;646 return -EOPNOTSUPP;
646 647
647 /* Fall-back to main clock in case of no PTP ref is passed */
648 priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref");
649 if (IS_ERR(priv->clk_ptp_ref)) {
650 priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk);
651 priv->clk_ptp_ref = NULL;
652 netdev_dbg(priv->dev, "PTP uses main clock\n");
653 } else {
654 clk_prepare_enable(priv->clk_ptp_ref);
655 priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref);
656 netdev_dbg(priv->dev, "PTP rate %d\n", priv->clk_ptp_rate);
657 }
658
659 priv->adv_ts = 0;648 priv->adv_ts = 0;
660 /* Check if adv_ts can be enabled for dwmac 4.x core */649 /* Check if adv_ts can be enabled for dwmac 4.x core */
661 if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp)650 if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp)
@@ -682,8 +671,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) · 20 unmodified lines
682 671
683static void stmmac_release_ptp(struct stmmac_priv *priv)672static void stmmac_release_ptp(struct stmmac_priv *priv)
684{673{
685 if (priv->clk_ptp_ref)674 if (priv->plat->clk_ptp_ref)
686 clk_disable_unprepare(priv->clk_ptp_ref);675 clk_disable_unprepare(priv->plat->clk_ptp_ref);
687 stmmac_ptp_unregister(priv);676 stmmac_ptp_unregister(priv);
688}677}
689 678
@@ -3277,44 +3266,8 @@ int stmmac_dvr_probe(struct device *device, · 2587 unmodified lines
3277 if ((phyaddr >= 0) && (phyaddr <= 31))3266 if ((phyaddr >= 0) && (phyaddr <= 31))
3278 priv->plat->phy_addr = phyaddr;3267 priv->plat->phy_addr = phyaddr;
3279 3268
3280 priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME);3269 if (priv->plat->stmmac_rst)
3281 if (IS_ERR(priv->stmmac_clk)) {3270 reset_control_deassert(priv->plat->stmmac_rst);
3282 netdev_warn(priv->dev, "%s: warning: cannot get CSR clock\n",
3283 __func__);
3284 /* If failed to obtain stmmac_clk and specific clk_csr value
3285 * is NOT passed from the platform, probe fail.
3286 */
3287 if (!priv->plat->clk_csr) {
3288 ret = PTR_ERR(priv->stmmac_clk);
3289 goto error_clk_get;
3290 } else {
3291 priv->stmmac_clk = NULL;
3292 }
3293 }
3294 clk_prepare_enable(priv->stmmac_clk);
3295
3296 priv->pclk = devm_clk_get(priv->device, "pclk");
3297 if (IS_ERR(priv->pclk)) {
3298 if (PTR_ERR(priv->pclk) == -EPROBE_DEFER) {
3299 ret = -EPROBE_DEFER;
3300 goto error_pclk_get;
3301 }
3302 priv->pclk = NULL;
3303 }
3304 clk_prepare_enable(priv->pclk);
3305
3306 priv->stmmac_rst = devm_reset_control_get(priv->device,
3307 STMMAC_RESOURCE_NAME);
3308 if (IS_ERR(priv->stmmac_rst)) {
3309 if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) {
3310 ret = -EPROBE_DEFER;
3311 goto error_hw_init;
3312 }
3313 dev_info(priv->device, "no reset control found\n");
3314 priv->stmmac_rst = NULL;
3315 }
3316 if (priv->stmmac_rst)
3317 reset_control_deassert(priv->stmmac_rst);
3318 3271
3319 /* Init MAC and get the capabilities */3272 /* Init MAC and get the capabilities */
3320 ret = stmmac_hw_init(priv);3273 ret = stmmac_hw_init(priv);
@@ -3408,10 +3361,6 @@ error_netdev_register: · 87 unmodified lines
3408error_mdio_register:3361error_mdio_register:
3409 netif_napi_del(&priv->napi);3362 netif_napi_del(&priv->napi);
3410error_hw_init:3363error_hw_init:
3411 clk_disable_unprepare(priv->pclk);
3412error_pclk_get:
3413 clk_disable_unprepare(priv->stmmac_clk);
3414error_clk_get:
3415 free_netdev(ndev);3364 free_netdev(ndev);
3416 3365
3417 return ret;3366 return ret;
@@ -3437,10 +3386,10 @@ int stmmac_dvr_remove(struct device *dev) · 19 unmodified lines
3437 stmmac_set_mac(priv->ioaddr, false);3386 stmmac_set_mac(priv->ioaddr, false);
3438 netif_carrier_off(ndev);3387 netif_carrier_off(ndev);
3439 unregister_netdev(ndev);3388 unregister_netdev(ndev);
3440 if (priv->stmmac_rst)3389 if (priv->plat->stmmac_rst)
3441 reset_control_assert(priv->stmmac_rst);3390 reset_control_assert(priv->plat->stmmac_rst);
3442 clk_disable_unprepare(priv->pclk);3391 clk_disable_unprepare(priv->plat->pclk);
3443 clk_disable_unprepare(priv->stmmac_clk);3392 clk_disable_unprepare(priv->plat->stmmac_clk);
3444 if (priv->hw->pcs != STMMAC_PCS_RGMII &&3393 if (priv->hw->pcs != STMMAC_PCS_RGMII &&
3445 priv->hw->pcs != STMMAC_PCS_TBI &&3394 priv->hw->pcs != STMMAC_PCS_TBI &&
3446 priv->hw->pcs != STMMAC_PCS_RTBI)3395 priv->hw->pcs != STMMAC_PCS_RTBI)
@@ -3489,8 +3438,8 @@ int stmmac_suspend(struct device *dev) · 42 unmodified lines
3489 stmmac_set_mac(priv->ioaddr, false);3438 stmmac_set_mac(priv->ioaddr, false);
3490 pinctrl_pm_select_sleep_state(priv->device);3439 pinctrl_pm_select_sleep_state(priv->device);
3491 /* Disable clock in case of PWM is off */3440 /* Disable clock in case of PWM is off */
3492 clk_disable(priv->pclk);3441 clk_disable(priv->plat->pclk);
3493 clk_disable(priv->stmmac_clk);3442 clk_disable(priv->plat->stmmac_clk);
3494 }3443 }
3495 spin_unlock_irqrestore(&priv->lock, flags);3444 spin_unlock_irqrestore(&priv->lock, flags);
3496 3445
@@ -3530,8 +3479,8 @@ int stmmac_resume(struct device *dev) · 33 unmodified lines
3530 } else {3479 } else {
3531 pinctrl_pm_select_default_state(priv->device);3480 pinctrl_pm_select_default_state(priv->device);
3532 /* enable the clk prevously disabled */3481 /* enable the clk prevously disabled */
3533 clk_enable(priv->stmmac_clk);3482 clk_enable(priv->plat->stmmac_clk);
3534 clk_enable(priv->pclk);3483 clk_enable(priv->plat->pclk);
3535 /* reset the phy so that it's ready */3484 /* reset the phy so that it's ready */
3536 if (priv->mii)3485 if (priv->mii)
3537 stmmac_mdio_reset(priv->mii);3486 stmmac_mdio_reset(priv->mii);
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c+62−3
@@ -180,10 +180,19 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, · 179 unmodified lines
180 mdio = false;180 mdio = false;
181 }181 }
182 182
183 /* If snps,dwmac-mdio is passed from DT, always register the MDIO */183 /* exception for dwmac-dwc-qos-eth glue logic */
184 for_each_child_of_node(np, plat->mdio_node) {184 if (of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) {
185 if (of_device_is_compatible(plat->mdio_node, "snps,dwmac-mdio"))185 plat->mdio_node = of_get_child_by_name(np, "mdio");
186 } else {
187 /**
188 * If snps,dwmac-mdio is passed from DT, always register
189 * the MDIO
190 */
191 for_each_child_of_node(np, plat->mdio_node) {
192 if (of_device_is_compatible(plat->mdio_node,
193 "snps,dwmac-mdio"))
186 break;194 break;
195 }
187 }196 }
188 197
189 if (plat->mdio_node) {198 if (plat->mdio_node) {
@@ -248,6 +257,9 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) · 58 unmodified lines
248 plat->force_sf_dma_mode =257 plat->force_sf_dma_mode =
249 of_property_read_bool(np, "snps,force_sf_dma_mode");258 of_property_read_bool(np, "snps,force_sf_dma_mode");
250 259
260 plat->en_tx_lpi_clockgating =
261 of_property_read_bool(np, "snps,en-tx-lpi-clockgating");
262
251 /* Set the maxmtu to a default of JUMBO_LEN in case the263 /* Set the maxmtu to a default of JUMBO_LEN in case the
252 * parameter is not present in the device tree.264 * parameter is not present in the device tree.
253 */265 */
@@ -332,7 +344,54 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) · 78 unmodified lines
332 344
333 plat->axi = stmmac_axi_setup(pdev);345 plat->axi = stmmac_axi_setup(pdev);
334 346
347 /* clock setup */
348 plat->stmmac_clk = devm_clk_get(&pdev->dev,
349 STMMAC_RESOURCE_NAME);
350 if (IS_ERR(plat->stmmac_clk)) {
351 dev_warn(&pdev->dev, "Cannot get CSR clock\n");
352 plat->stmmac_clk = NULL;
353 }
354 clk_prepare_enable(plat->stmmac_clk);
355
356 plat->pclk = devm_clk_get(&pdev->dev, "pclk");
357 if (IS_ERR(plat->pclk)) {
358 if (PTR_ERR(plat->pclk) == -EPROBE_DEFER)
359 goto error_pclk_get;
360
361 plat->pclk = NULL;
362 }
363 clk_prepare_enable(plat->pclk);
364
365 /* Fall-back to main clock in case of no PTP ref is passed */
366 plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "clk_ptp_ref");
367 if (IS_ERR(plat->clk_ptp_ref)) {
368 plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
369 plat->clk_ptp_ref = NULL;
370 dev_warn(&pdev->dev, "PTP uses main clock\n");
371 } else {
372 clk_prepare_enable(plat->clk_ptp_ref);
373 plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
374 dev_info(&pdev->dev, "No reset control found\n");
375 }
376
377 plat->stmmac_rst = devm_reset_control_get(&pdev->dev,
378 STMMAC_RESOURCE_NAME);
379 if (IS_ERR(plat->stmmac_rst)) {
380 if (PTR_ERR(plat->stmmac_rst) == -EPROBE_DEFER)
381 goto error_hw_init;
382
383 dev_info(&pdev->dev, "no reset control found\n");
384 plat->stmmac_rst = NULL;
385 }
386
335 return plat;387 return plat;
388
389error_hw_init:
390 clk_disable_unprepare(plat->pclk);
391error_pclk_get:
392 clk_disable_unprepare(plat->stmmac_clk);
393
394 return ERR_PTR(-EPROBE_DEFER);
336}395}
337 396
338/**397/**
include/linux/stmmac.h+6−0
@@ -138,9 +138,15 @@ struct plat_stmmacenet_data { · 137 unmodified lines
138 int (*init)(struct platform_device *pdev, void *priv);138 int (*init)(struct platform_device *pdev, void *priv);
139 void (*exit)(struct platform_device *pdev, void *priv);139 void (*exit)(struct platform_device *pdev, void *priv);
140 void *bsp_priv;140 void *bsp_priv;
141 struct clk *stmmac_clk;
142 struct clk *pclk;
143 struct clk *clk_ptp_ref;
144 unsigned int clk_ptp_rate;
145 struct reset_control *stmmac_rst;
141 struct stmmac_axi *axi;146 struct stmmac_axi *axi;
142 int has_gmac4;147 int has_gmac4;
143 bool tso_en;148 bool tso_en;
144 int mac_port_sel_speed;149 int mac_port_sel_speed;
150 bool en_tx_lpi_clockgating;
145};151};
146#endif152#endif