xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
1 /**
2  * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer
3  *
4  * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
5  * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
6  *
7  *
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
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/platform_device.h>
17 #include <linux/stmmac.h>
18 #include <linux/phy.h>
19 #include <linux/mfd/syscon.h>
20 #include <linux/regmap.h>
21 #include <linux/clk.h>
22 #include <linux/of.h>
23 #include <linux/of_net.h>
24 
25 /**
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
65  * supported phy interface modes with link speeds.
66  * ________________________________________________
67  *|  PHY_MODE	| 1000 Mbit Link | 100 Mbit Link   |
68  * ------------------------------------------------
69  *|	MII	|	n/a	 |	25Mhz	   |
70  *|		|		 |	txclk	   |
71  * ------------------------------------------------
72  *|	GMII	|     125Mhz	 |	25Mhz	   |
73  *|		|  clk-125/txclk |	txclk	   |
74  * ------------------------------------------------
75  *|	RGMII	|     125Mhz	 |	25Mhz	   |
76  *|		|  clk-125/txclk |	clkgen     |
77  * ------------------------------------------------
78  *|	RMII	|	n/a	 |	25Mhz	   |
79  *|		|		 |clkgen/phyclk-in |
80  * ------------------------------------------------
81  *
82  * TX lines are always retimed with a clk, which can vary depending
83  * on the board configuration. Below is the table of these bits
84  * in eth configuration register depending on source of retime clk.
85  *
86  *---------------------------------------------------------------
87  * src	 | tx_rt_clk	| int_not_ext_phyclk	| txclk_n_clk125|
88  *---------------------------------------------------------------
89  * txclk |	0	|	n/a		|	1	|
90  *---------------------------------------------------------------
91  * ck_125|	0	|	n/a		|	0	|
92  *---------------------------------------------------------------
93  * phyclk|	1	|	0		|	n/a	|
94  *---------------------------------------------------------------
95  * clkgen|	1	|	1		|	n/a	|
96  *---------------------------------------------------------------
97  */
98 
99  /* Register definition */
100 
101  /* 3 bits [8:6]
102   *  [6:6]      ETH_SEL_TXCLK_NOT_CLK125
103   *  [7:7]      ETH_SEL_INTERNAL_NOTEXT_PHYCLK
104   *  [8:8]      ETH_SEL_TX_RETIME_CLK
105   *
106   */
107 
108 #define TX_RETIME_SRC_MASK		GENMASK(8, 6)
109 #define ETH_SEL_TX_RETIME_CLK		BIT(8)
110 #define ETH_SEL_INTERNAL_NOTEXT_PHYCLK	BIT(7)
111 #define ETH_SEL_TXCLK_NOT_CLK125	BIT(6)
112 
113 #define ENMII_MASK			GENMASK(5, 5)
114 #define ENMII				BIT(5)
115 
116 /**
117  * 3 bits [4:2]
118  *	000-GMII/MII
119  *	001-RGMII
120  *	010-SGMII
121  *	100-RMII
122 */
123 #define MII_PHY_SEL_MASK		GENMASK(4, 2)
124 #define ETH_PHY_SEL_RMII		BIT(4)
125 #define ETH_PHY_SEL_SGMII		BIT(3)
126 #define ETH_PHY_SEL_RGMII		BIT(2)
127 #define ETH_PHY_SEL_GMII		0x0
128 #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 
138 struct sti_dwmac {
139 	int interface;
140 	bool ext_phyclk;
141 	bool is_tx_retime_src_clk_125;
142 	struct clk *clk;
143 	int reg;
144 	struct device *dev;
145 	struct regmap *regmap;
146 };
147 
148 static u32 phy_intf_sels[] = {
149 	[PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII,
150 	[PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII,
151 	[PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII,
152 	[PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII,
153 	[PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII,
154 	[PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII,
155 };
156 
157 enum {
158 	TX_RETIME_SRC_NA = 0,
159 	TX_RETIME_SRC_TXCLK = 1,
160 	TX_RETIME_SRC_CLK_125,
161 	TX_RETIME_SRC_PHYCLK,
162 	TX_RETIME_SRC_CLKGEN,
163 };
164 
165 static const char *const tx_retime_srcs[] = {
166 	[TX_RETIME_SRC_NA] = "",
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 
173 static u32 tx_retime_val[] = {
174 	[TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125,
175 	[TX_RETIME_SRC_CLK_125] = 0x0,
176 	[TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK,
177 	[TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK |
178 	    ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
179 };
180 
181 static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd)
182 {
183 	u32 src = 0, freq = 0;
184 
185 	if (spd == SPEED_100) {
186 		if (dwmac->interface == PHY_INTERFACE_MODE_MII ||
187 		    dwmac->interface == PHY_INTERFACE_MODE_GMII) {
188 			src = TX_RETIME_SRC_TXCLK;
189 		} else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
190 			if (dwmac->ext_phyclk) {
191 				src = TX_RETIME_SRC_PHYCLK;
192 			} else {
193 				src = TX_RETIME_SRC_CLKGEN;
194 				freq = 50000000;
195 			}
196 
197 		} else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
198 			src = TX_RETIME_SRC_CLKGEN;
199 			freq = 25000000;
200 		}
201 
202 		if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk)
203 			clk_set_rate(dwmac->clk, freq);
204 
205 	} else if (spd == SPEED_1000) {
206 		if (dwmac->is_tx_retime_src_clk_125)
207 			src = TX_RETIME_SRC_CLK_125;
208 		else
209 			src = TX_RETIME_SRC_TXCLK;
210 	}
211 
212 	regmap_update_bits(dwmac->regmap, dwmac->reg,
213 			   TX_RETIME_SRC_MASK, tx_retime_val[src]);
214 }
215 
216 static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
217 {
218 	struct sti_dwmac *dwmac = priv;
219 
220 	if (dwmac->clk)
221 		clk_disable_unprepare(dwmac->clk);
222 }
223 
224 static void sti_fix_mac_speed(void *priv, unsigned int spd)
225 {
226 	struct sti_dwmac *dwmac = priv;
227 
228 	setup_retime_src(dwmac, spd);
229 
230 	return;
231 }
232 
233 static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
234 				struct platform_device *pdev)
235 {
236 	struct resource *res;
237 	struct device *dev = &pdev->dev;
238 	struct device_node *np = dev->of_node;
239 	struct regmap *regmap;
240 	int err;
241 
242 	if (!np)
243 		return -EINVAL;
244 
245 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
246 	if (!res)
247 		return -ENODATA;
248 
249 	regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
250 	if (IS_ERR(regmap))
251 		return PTR_ERR(regmap);
252 
253 	dwmac->dev = dev;
254 	dwmac->interface = of_get_phy_mode(np);
255 	dwmac->regmap = regmap;
256 	dwmac->reg = res->start;
257 	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
258 	dwmac->is_tx_retime_src_clk_125 = false;
259 
260 	if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
261 		const char *rs;
262 
263 		err = of_property_read_string(np, "st,tx-retime-src", &rs);
264 		if (err < 0) {
265 			dev_err(dev, "st,tx-retime-src not specified\n");
266 			return err;
267 		}
268 
269 		if (!strcasecmp(rs, "clk_125"))
270 			dwmac->is_tx_retime_src_clk_125 = true;
271 	}
272 
273 	dwmac->clk = devm_clk_get(dev, "sti-ethclk");
274 
275 	if (IS_ERR(dwmac->clk))
276 		dwmac->clk = NULL;
277 
278 	return 0;
279 }
280 
281 static 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 
304 	return 0;
305 }
306 
307 static void *sti_dwmac_setup(struct platform_device *pdev)
308 {
309 	struct sti_dwmac *dwmac;
310 	int ret;
311 
312 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
313 	if (!dwmac)
314 		return ERR_PTR(-ENOMEM);
315 
316 	ret = sti_dwmac_parse_data(dwmac, pdev);
317 	if (ret) {
318 		dev_err(&pdev->dev, "Unable to parse OF data\n");
319 		return ERR_PTR(ret);
320 	}
321 
322 	return dwmac;
323 }
324 
325 const struct stmmac_of_data sti_gmac_data = {
326 	.fix_mac_speed = sti_fix_mac_speed,
327 	.setup = sti_dwmac_setup,
328 	.init = sti_dwmac_init,
329 	.exit = sti_dwmac_exit,
330 };
331