aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c374
1 files changed, 205 insertions, 169 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index 552bbc17863c..ccfe7e510418 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited 4 * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
5 * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> 5 * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
6 * 6 * Contributors: Giuseppe Cavallaro <peppe.cavallaro@st.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -22,45 +22,22 @@
22#include <linux/of.h> 22#include <linux/of.h>
23#include <linux/of_net.h> 23#include <linux/of_net.h>
24 24
25#define DWMAC_125MHZ 125000000
26#define DWMAC_50MHZ 50000000
27#define DWMAC_25MHZ 25000000
28#define DWMAC_2_5MHZ 2500000
29
30#define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
31 iface == PHY_INTERFACE_MODE_RGMII_ID || \
32 iface == PHY_INTERFACE_MODE_RGMII_RXID || \
33 iface == PHY_INTERFACE_MODE_RGMII_TXID)
34
35#define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
36 iface == PHY_INTERFACE_MODE_GMII)
37
38/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) */
39
25/** 40/**
26 * STi GMAC glue logic.
27 * --------------------
28 *
29 * _
30 * | \
31 * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK
32 * phyclk | |___________________________________________
33 * | | | (phyclk-in)
34 * --------|1 / |
35 * int-clk |_ / |
36 * | _
37 * | | \
38 * |_______|1 \ ETH_SEL_TX_RETIME_CLK
39 * | |___________________________
40 * | | (tx-retime-clk)
41 * _______|0 /
42 * | |_ /
43 * _ |
44 * | \ |
45 * --------|0 \ |
46 * clk_125 | |__|
47 * | | ETH_SEL_TXCLK_NOT_CLK125
48 * --------|1 /
49 * txclk |_ /
50 *
51 *
52 * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can
53 * generate 50MHz clock or MAC can generate it.
54 * This bit is configured by "st,ext-phyclk" property.
55 *
56 * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz
57 * clock either comes from clk-125 pin or txclk pin. This configuration is
58 * totally driven by the board wiring. This bit is configured by
59 * "st,tx-retime-src" property.
60 *
61 * TXCLK configuration is different for different phy interface modes
62 * and changes according to link speed in modes like RGMII.
63 *
64 * Below table summarizes the clock requirement and clock sources for 41 * Below table summarizes the clock requirement and clock sources for
65 * supported phy interface modes with link speeds. 42 * supported phy interface modes with link speeds.
66 * ________________________________________________ 43 * ________________________________________________
@@ -74,44 +51,58 @@
74 * ------------------------------------------------ 51 * ------------------------------------------------
75 *| RGMII | 125Mhz | 25Mhz | 52 *| RGMII | 125Mhz | 25Mhz |
76 *| | clk-125/txclk | clkgen | 53 *| | clk-125/txclk | clkgen |
54 *| | clkgen | |
77 * ------------------------------------------------ 55 * ------------------------------------------------
78 *| RMII | n/a | 25Mhz | 56 *| RMII | n/a | 25Mhz |
79 *| | |clkgen/phyclk-in | 57 *| | |clkgen/phyclk-in |
80 * ------------------------------------------------ 58 * ------------------------------------------------
81 * 59 *
82 * TX lines are always retimed with a clk, which can vary depending 60 * Register Configuration
83 * on the board configuration. Below is the table of these bits 61 *-------------------------------
84 * in eth configuration register depending on source of retime clk. 62 * src |BIT(8)| BIT(7)| BIT(6)|
85 * 63 *-------------------------------
86 *--------------------------------------------------------------- 64 * txclk | 0 | n/a | 1 |
87 * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125| 65 *-------------------------------
88 *--------------------------------------------------------------- 66 * ck_125| 0 | n/a | 0 |
89 * txclk | 0 | n/a | 1 | 67 *-------------------------------
90 *--------------------------------------------------------------- 68 * phyclk| 1 | 0 | n/a |
91 * ck_125| 0 | n/a | 0 | 69 *-------------------------------
92 *--------------------------------------------------------------- 70 * clkgen| 1 | 1 | n/a |
93 * phyclk| 1 | 0 | n/a | 71 *-------------------------------
94 *---------------------------------------------------------------
95 * clkgen| 1 | 1 | n/a |
96 *---------------------------------------------------------------
97 */ 72 */
98 73
99 /* Register definition */ 74#define STIH4XX_RETIME_SRC_MASK GENMASK(8, 6)
75#define STIH4XX_ETH_SEL_TX_RETIME_CLK BIT(8)
76#define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
77#define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
78
79/* STiD127 register definitions */
100 80
101 /* 3 bits [8:6] 81/**
102 * [6:6] ETH_SEL_TXCLK_NOT_CLK125 82 *-----------------------
103 * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK 83 * src |BIT(6)| BIT(7)|
104 * [8:8] ETH_SEL_TX_RETIME_CLK 84 *-----------------------
105 * 85 * MII | 1 | n/a |
106 */ 86 *-----------------------
87 * RMII | n/a | 1 |
88 * clkgen| | |
89 *-----------------------
90 * RMII | n/a | 0 |
91 * phyclk| | |
92 *-----------------------
93 * RGMII | 1 | n/a |
94 * clkgen| | |
95 *-----------------------
96 */
107 97
108#define TX_RETIME_SRC_MASK GENMASK(8, 6) 98#define STID127_RETIME_SRC_MASK GENMASK(7, 6)
109#define ETH_SEL_TX_RETIME_CLK BIT(8) 99#define STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
110#define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) 100#define STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK BIT(6)
111#define ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
112 101
113#define ENMII_MASK GENMASK(5, 5) 102#define ENMII_MASK GENMASK(5, 5)
114#define ENMII BIT(5) 103#define ENMII BIT(5)
104#define EN_MASK GENMASK(1, 1)
105#define EN BIT(1)
115 106
116/** 107/**
117 * 3 bits [4:2] 108 * 3 bits [4:2]
@@ -120,29 +111,23 @@
120 * 010-SGMII 111 * 010-SGMII
121 * 100-RMII 112 * 100-RMII
122*/ 113*/
123#define MII_PHY_SEL_MASK GENMASK(4, 2) 114#define MII_PHY_SEL_MASK GENMASK(4, 2)
124#define ETH_PHY_SEL_RMII BIT(4) 115#define ETH_PHY_SEL_RMII BIT(4)
125#define ETH_PHY_SEL_SGMII BIT(3) 116#define ETH_PHY_SEL_SGMII BIT(3)
126#define ETH_PHY_SEL_RGMII BIT(2) 117#define ETH_PHY_SEL_RGMII BIT(2)
127#define ETH_PHY_SEL_GMII 0x0 118#define ETH_PHY_SEL_GMII 0x0
128#define ETH_PHY_SEL_MII 0x0 119#define ETH_PHY_SEL_MII 0x0
129
130#define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
131 iface == PHY_INTERFACE_MODE_RGMII_ID || \
132 iface == PHY_INTERFACE_MODE_RGMII_RXID || \
133 iface == PHY_INTERFACE_MODE_RGMII_TXID)
134
135#define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
136 iface == PHY_INTERFACE_MODE_GMII)
137 120
138struct sti_dwmac { 121struct sti_dwmac {
139 int interface; 122 int interface; /* MII interface */
140 bool ext_phyclk; 123 bool ext_phyclk; /* Clock from external PHY */
141 bool is_tx_retime_src_clk_125; 124 u32 tx_retime_src; /* TXCLK Retiming*/
142 struct clk *clk; 125 struct clk *clk; /* PHY clock */
143 int reg; 126 int ctrl_reg; /* GMAC glue-logic control register */
127 int clk_sel_reg; /* GMAC ext clk selection register */
144 struct device *dev; 128 struct device *dev;
145 struct regmap *regmap; 129 struct regmap *regmap;
130 u32 speed;
146}; 131};
147 132
148static u32 phy_intf_sels[] = { 133static u32 phy_intf_sels[] = {
@@ -162,74 +147,133 @@ enum {
162 TX_RETIME_SRC_CLKGEN, 147 TX_RETIME_SRC_CLKGEN,
163}; 148};
164 149
165static const char *const tx_retime_srcs[] = { 150static u32 stih4xx_tx_retime_val[] = {
166 [TX_RETIME_SRC_NA] = "", 151 [TX_RETIME_SRC_TXCLK] = STIH4XX_ETH_SEL_TXCLK_NOT_CLK125,
167 [TX_RETIME_SRC_TXCLK] = "txclk",
168 [TX_RETIME_SRC_CLK_125] = "clk_125",
169 [TX_RETIME_SRC_PHYCLK] = "phyclk",
170 [TX_RETIME_SRC_CLKGEN] = "clkgen",
171};
172
173static u32 tx_retime_val[] = {
174 [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125,
175 [TX_RETIME_SRC_CLK_125] = 0x0, 152 [TX_RETIME_SRC_CLK_125] = 0x0,
176 [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, 153 [TX_RETIME_SRC_PHYCLK] = STIH4XX_ETH_SEL_TX_RETIME_CLK,
177 [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | 154 [TX_RETIME_SRC_CLKGEN] = STIH4XX_ETH_SEL_TX_RETIME_CLK
178 ETH_SEL_INTERNAL_NOTEXT_PHYCLK, 155 | STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
179}; 156};
180 157
181static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) 158static void stih4xx_fix_retime_src(void *priv, u32 spd)
182{ 159{
183 u32 src = 0, freq = 0; 160 struct sti_dwmac *dwmac = priv;
184 161 u32 src = dwmac->tx_retime_src;
185 if (spd == SPEED_100) { 162 u32 reg = dwmac->ctrl_reg;
186 if (dwmac->interface == PHY_INTERFACE_MODE_MII || 163 u32 freq = 0;
187 dwmac->interface == PHY_INTERFACE_MODE_GMII) { 164
188 src = TX_RETIME_SRC_TXCLK; 165 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
189 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { 166 src = TX_RETIME_SRC_TXCLK;
190 if (dwmac->ext_phyclk) { 167 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
191 src = TX_RETIME_SRC_PHYCLK; 168 if (dwmac->ext_phyclk) {
192 } else { 169 src = TX_RETIME_SRC_PHYCLK;
193 src = TX_RETIME_SRC_CLKGEN; 170 } else {
194 freq = 50000000;
195 }
196
197 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
198 src = TX_RETIME_SRC_CLKGEN; 171 src = TX_RETIME_SRC_CLKGEN;
199 freq = 25000000; 172 freq = DWMAC_50MHZ;
200 } 173 }
174 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
175 /* On GiGa clk source can be either ext or from clkgen */
176 if (spd == SPEED_1000) {
177 freq = DWMAC_125MHZ;
178 } else {
179 /* Switch to clkgen for these speeds */
180 src = TX_RETIME_SRC_CLKGEN;
181 if (spd == SPEED_100)
182 freq = DWMAC_25MHZ;
183 else if (spd == SPEED_10)
184 freq = DWMAC_2_5MHZ;
185 }
186 }
201 187
202 if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) 188 if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk && freq)
203 clk_set_rate(dwmac->clk, freq); 189 clk_set_rate(dwmac->clk, freq);
204 190
205 } else if (spd == SPEED_1000) { 191 regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,
206 if (dwmac->is_tx_retime_src_clk_125) 192 stih4xx_tx_retime_val[src]);
207 src = TX_RETIME_SRC_CLK_125; 193}
208 else 194
209 src = TX_RETIME_SRC_TXCLK; 195static void stid127_fix_retime_src(void *priv, u32 spd)
196{
197 struct sti_dwmac *dwmac = priv;
198 u32 reg = dwmac->ctrl_reg;
199 u32 freq = 0;
200 u32 val = 0;
201
202 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
203 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
204 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
205 if (!dwmac->ext_phyclk) {
206 val = STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK;
207 freq = DWMAC_50MHZ;
208 }
209 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
210 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
211 if (spd == SPEED_1000)
212 freq = DWMAC_125MHZ;
213 else if (spd == SPEED_100)
214 freq = DWMAC_25MHZ;
215 else if (spd == SPEED_10)
216 freq = DWMAC_2_5MHZ;
210 } 217 }
211 218
212 regmap_update_bits(dwmac->regmap, dwmac->reg, 219 if (dwmac->clk && freq)
213 TX_RETIME_SRC_MASK, tx_retime_val[src]); 220 clk_set_rate(dwmac->clk, freq);
221
222 regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
214} 223}
215 224
216static void sti_dwmac_exit(struct platform_device *pdev, void *priv) 225static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
217{ 226{
218 struct sti_dwmac *dwmac = priv; 227 struct regmap *regmap = dwmac->regmap;
228 int iface = dwmac->interface;
229 struct device *dev = dwmac->dev;
230 struct device_node *np = dev->of_node;
231 u32 reg = dwmac->ctrl_reg;
232 u32 val;
219 233
220 if (dwmac->clk) 234 if (dwmac->clk)
221 clk_disable_unprepare(dwmac->clk); 235 clk_prepare_enable(dwmac->clk);
236
237 if (of_property_read_bool(np, "st,gmac_en"))
238 regmap_update_bits(regmap, reg, EN_MASK, EN);
239
240 regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
241
242 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
243 regmap_update_bits(regmap, reg, ENMII_MASK, val);
244}
245
246static int stix4xx_init(struct platform_device *pdev, void *priv)
247{
248 struct sti_dwmac *dwmac = priv;
249 u32 spd = dwmac->speed;
250
251 sti_dwmac_ctrl_init(dwmac);
252
253 stih4xx_fix_retime_src(priv, spd);
254
255 return 0;
222} 256}
223 257
224static void sti_fix_mac_speed(void *priv, unsigned int spd) 258static int stid127_init(struct platform_device *pdev, void *priv)
225{ 259{
226 struct sti_dwmac *dwmac = priv; 260 struct sti_dwmac *dwmac = priv;
261 u32 spd = dwmac->speed;
227 262
228 setup_retime_src(dwmac, spd); 263 sti_dwmac_ctrl_init(dwmac);
229 264
230 return; 265 stid127_fix_retime_src(priv, spd);
266
267 return 0;
231} 268}
232 269
270static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
271{
272 struct sti_dwmac *dwmac = priv;
273
274 if (dwmac->clk)
275 clk_disable_unprepare(dwmac->clk);
276}
233static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, 277static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
234 struct platform_device *pdev) 278 struct platform_device *pdev)
235{ 279{
@@ -245,6 +289,13 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
245 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); 289 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
246 if (!res) 290 if (!res)
247 return -ENODATA; 291 return -ENODATA;
292 dwmac->ctrl_reg = res->start;
293
294 /* clk selection from extra syscfg register */
295 dwmac->clk_sel_reg = -ENXIO;
296 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
297 if (res)
298 dwmac->clk_sel_reg = res->start;
248 299
249 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); 300 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
250 if (IS_ERR(regmap)) 301 if (IS_ERR(regmap))
@@ -253,53 +304,31 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
253 dwmac->dev = dev; 304 dwmac->dev = dev;
254 dwmac->interface = of_get_phy_mode(np); 305 dwmac->interface = of_get_phy_mode(np);
255 dwmac->regmap = regmap; 306 dwmac->regmap = regmap;
256 dwmac->reg = res->start;
257 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); 307 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
258 dwmac->is_tx_retime_src_clk_125 = false; 308 dwmac->tx_retime_src = TX_RETIME_SRC_NA;
309 dwmac->speed = SPEED_100;
259 310
260 if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { 311 if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
261 const char *rs; 312 const char *rs;
313 dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
262 314
263 err = of_property_read_string(np, "st,tx-retime-src", &rs); 315 err = of_property_read_string(np, "st,tx-retime-src", &rs);
264 if (err < 0) { 316 if (err < 0)
265 dev_err(dev, "st,tx-retime-src not specified\n"); 317 dev_warn(dev, "Use internal clock source\n");
266 return err;
267 }
268 318
269 if (!strcasecmp(rs, "clk_125")) 319 if (!strcasecmp(rs, "clk_125"))
270 dwmac->is_tx_retime_src_clk_125 = true; 320 dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
321 else if (!strcasecmp(rs, "txclk"))
322 dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
323
324 dwmac->speed = SPEED_1000;
271 } 325 }
272 326
273 dwmac->clk = devm_clk_get(dev, "sti-ethclk"); 327 dwmac->clk = devm_clk_get(dev, "sti-ethclk");
274 328 if (IS_ERR(dwmac->clk)) {
275 if (IS_ERR(dwmac->clk)) 329 dev_warn(dev, "No phy clock provided...\n");
276 dwmac->clk = NULL; 330 dwmac->clk = NULL;
277 331 }
278 return 0;
279}
280
281static int sti_dwmac_init(struct platform_device *pdev, void *priv)
282{
283 struct sti_dwmac *dwmac = priv;
284 struct regmap *regmap = dwmac->regmap;
285 int iface = dwmac->interface;
286 u32 reg = dwmac->reg;
287 u32 val, spd;
288
289 if (dwmac->clk)
290 clk_prepare_enable(dwmac->clk);
291
292 regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
293
294 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
295 regmap_update_bits(regmap, reg, ENMII_MASK, val);
296
297 if (IS_PHY_IF_MODE_GBIT(iface))
298 spd = SPEED_1000;
299 else
300 spd = SPEED_100;
301
302 setup_retime_src(dwmac, spd);
303 332
304 return 0; 333 return 0;
305} 334}
@@ -322,9 +351,16 @@ static void *sti_dwmac_setup(struct platform_device *pdev)
322 return dwmac; 351 return dwmac;
323} 352}
324 353
325const struct stmmac_of_data sti_gmac_data = { 354const struct stmmac_of_data stih4xx_dwmac_data = {
326 .fix_mac_speed = sti_fix_mac_speed, 355 .fix_mac_speed = stih4xx_fix_retime_src,
356 .setup = sti_dwmac_setup,
357 .init = stix4xx_init,
358 .exit = sti_dwmac_exit,
359};
360
361const struct stmmac_of_data stid127_dwmac_data = {
362 .fix_mac_speed = stid127_fix_retime_src,
327 .setup = sti_dwmac_setup, 363 .setup = sti_dwmac_setup,
328 .init = sti_dwmac_init, 364 .init = stid127_init,
329 .exit = sti_dwmac_exit, 365 .exit = sti_dwmac_exit,
330}; 366};