2 * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer
4 * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
5 * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
6 * Contributors: Giuseppe Cavallaro <peppe.cavallaro@st.com>
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.
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>
23 #include <linux/of_net.h>
25 #include "stmmac_platform.h"
27 #define DWMAC_125MHZ 125000000
28 #define DWMAC_50MHZ 50000000
29 #define DWMAC_25MHZ 25000000
30 #define DWMAC_2_5MHZ 2500000
32 #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \
33 iface == PHY_INTERFACE_MODE_RGMII_ID || \
34 iface == PHY_INTERFACE_MODE_RGMII_RXID || \
35 iface == PHY_INTERFACE_MODE_RGMII_TXID)
37 #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \
38 iface == PHY_INTERFACE_MODE_GMII)
40 /* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) */
43 * Below table summarizes the clock requirement and clock sources for
44 * supported phy interface modes with link speeds.
45 * ________________________________________________
46 *| PHY_MODE | 1000 Mbit Link | 100 Mbit Link |
47 * ------------------------------------------------
48 *| MII | n/a | 25Mhz |
50 * ------------------------------------------------
51 *| GMII | 125Mhz | 25Mhz |
52 *| | clk-125/txclk | txclk |
53 * ------------------------------------------------
54 *| RGMII | 125Mhz | 25Mhz |
55 *| | clk-125/txclk | clkgen |
57 * ------------------------------------------------
58 *| RMII | n/a | 25Mhz |
59 *| | |clkgen/phyclk-in |
60 * ------------------------------------------------
62 * Register Configuration
63 *-------------------------------
64 * src |BIT(8)| BIT(7)| BIT(6)|
65 *-------------------------------
66 * txclk | 0 | n/a | 1 |
67 *-------------------------------
68 * ck_125| 0 | n/a | 0 |
69 *-------------------------------
70 * phyclk| 1 | 0 | n/a |
71 *-------------------------------
72 * clkgen| 1 | 1 | n/a |
73 *-------------------------------
76 #define STIH4XX_RETIME_SRC_MASK GENMASK(8, 6)
77 #define STIH4XX_ETH_SEL_TX_RETIME_CLK BIT(8)
78 #define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
79 #define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125 BIT(6)
81 /* STiD127 register definitions */
84 *-----------------------
85 * src |BIT(6)| BIT(7)|
86 *-----------------------
88 *-----------------------
91 *-----------------------
94 *-----------------------
97 *-----------------------
100 #define STID127_RETIME_SRC_MASK GENMASK(7, 6)
101 #define STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7)
102 #define STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK BIT(6)
104 #define ENMII_MASK GENMASK(5, 5)
106 #define EN_MASK GENMASK(1, 1)
116 #define MII_PHY_SEL_MASK GENMASK(4, 2)
117 #define ETH_PHY_SEL_RMII BIT(4)
118 #define ETH_PHY_SEL_SGMII BIT(3)
119 #define ETH_PHY_SEL_RGMII BIT(2)
120 #define ETH_PHY_SEL_GMII 0x0
121 #define ETH_PHY_SEL_MII 0x0
124 int interface; /* MII interface */
125 bool ext_phyclk; /* Clock from external PHY */
126 u32 tx_retime_src; /* TXCLK Retiming*/
127 struct clk *clk; /* PHY clock */
128 int ctrl_reg; /* GMAC glue-logic control register */
129 int clk_sel_reg; /* GMAC ext clk selection register */
131 struct regmap *regmap;
135 static u32 phy_intf_sels[] = {
136 [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII,
137 [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII,
138 [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII,
139 [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII,
140 [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII,
141 [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII,
145 TX_RETIME_SRC_NA = 0,
146 TX_RETIME_SRC_TXCLK = 1,
147 TX_RETIME_SRC_CLK_125,
148 TX_RETIME_SRC_PHYCLK,
149 TX_RETIME_SRC_CLKGEN,
152 static u32 stih4xx_tx_retime_val[] = {
153 [TX_RETIME_SRC_TXCLK] = STIH4XX_ETH_SEL_TXCLK_NOT_CLK125,
154 [TX_RETIME_SRC_CLK_125] = 0x0,
155 [TX_RETIME_SRC_PHYCLK] = STIH4XX_ETH_SEL_TX_RETIME_CLK,
156 [TX_RETIME_SRC_CLKGEN] = STIH4XX_ETH_SEL_TX_RETIME_CLK
157 | STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
160 static void stih4xx_fix_retime_src(void *priv, u32 spd)
162 struct sti_dwmac *dwmac = priv;
163 u32 src = dwmac->tx_retime_src;
164 u32 reg = dwmac->ctrl_reg;
167 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
168 src = TX_RETIME_SRC_TXCLK;
169 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
170 if (dwmac->ext_phyclk) {
171 src = TX_RETIME_SRC_PHYCLK;
173 src = TX_RETIME_SRC_CLKGEN;
176 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
177 /* On GiGa clk source can be either ext or from clkgen */
178 if (spd == SPEED_1000) {
181 /* Switch to clkgen for these speeds */
182 src = TX_RETIME_SRC_CLKGEN;
183 if (spd == SPEED_100)
185 else if (spd == SPEED_10)
190 if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk && freq)
191 clk_set_rate(dwmac->clk, freq);
193 regmap_update_bits(dwmac->regmap, reg, STIH4XX_RETIME_SRC_MASK,
194 stih4xx_tx_retime_val[src]);
197 static void stid127_fix_retime_src(void *priv, u32 spd)
199 struct sti_dwmac *dwmac = priv;
200 u32 reg = dwmac->ctrl_reg;
204 if (dwmac->interface == PHY_INTERFACE_MODE_MII) {
205 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
206 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
207 if (!dwmac->ext_phyclk) {
208 val = STID127_ETH_SEL_INTERNAL_NOTEXT_PHYCLK;
211 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
212 val = STID127_ETH_SEL_INTERNAL_NOTEXT_TXCLK;
213 if (spd == SPEED_1000)
215 else if (spd == SPEED_100)
217 else if (spd == SPEED_10)
221 if (dwmac->clk && freq)
222 clk_set_rate(dwmac->clk, freq);
224 regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
227 static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
229 struct regmap *regmap = dwmac->regmap;
230 int iface = dwmac->interface;
231 struct device *dev = dwmac->dev;
232 struct device_node *np = dev->of_node;
233 u32 reg = dwmac->ctrl_reg;
237 clk_prepare_enable(dwmac->clk);
239 if (of_property_read_bool(np, "st,gmac_en"))
240 regmap_update_bits(regmap, reg, EN_MASK, EN);
242 regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
244 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
245 regmap_update_bits(regmap, reg, ENMII_MASK, val);
248 static int stix4xx_init(struct platform_device *pdev, void *priv)
250 struct sti_dwmac *dwmac = priv;
251 u32 spd = dwmac->speed;
253 sti_dwmac_ctrl_init(dwmac);
255 stih4xx_fix_retime_src(priv, spd);
260 static int stid127_init(struct platform_device *pdev, void *priv)
262 struct sti_dwmac *dwmac = priv;
263 u32 spd = dwmac->speed;
265 sti_dwmac_ctrl_init(dwmac);
267 stid127_fix_retime_src(priv, spd);
272 static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
274 struct sti_dwmac *dwmac = priv;
277 clk_disable_unprepare(dwmac->clk);
279 static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
280 struct platform_device *pdev)
282 struct resource *res;
283 struct device *dev = &pdev->dev;
284 struct device_node *np = dev->of_node;
285 struct regmap *regmap;
291 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
294 dwmac->ctrl_reg = res->start;
296 /* clk selection from extra syscfg register */
297 dwmac->clk_sel_reg = -ENXIO;
298 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
300 dwmac->clk_sel_reg = res->start;
302 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
304 return PTR_ERR(regmap);
307 dwmac->interface = of_get_phy_mode(np);
308 dwmac->regmap = regmap;
309 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
310 dwmac->tx_retime_src = TX_RETIME_SRC_NA;
311 dwmac->speed = SPEED_100;
313 if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
315 dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
317 err = of_property_read_string(np, "st,tx-retime-src", &rs);
319 dev_warn(dev, "Use internal clock source\n");
321 if (!strcasecmp(rs, "clk_125"))
322 dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
323 else if (!strcasecmp(rs, "txclk"))
324 dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
326 dwmac->speed = SPEED_1000;
329 dwmac->clk = devm_clk_get(dev, "sti-ethclk");
330 if (IS_ERR(dwmac->clk)) {
331 dev_warn(dev, "No phy clock provided...\n");
338 static void *sti_dwmac_setup(struct platform_device *pdev)
340 struct sti_dwmac *dwmac;
343 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
345 return ERR_PTR(-ENOMEM);
347 ret = sti_dwmac_parse_data(dwmac, pdev);
349 dev_err(&pdev->dev, "Unable to parse OF data\n");
356 const struct stmmac_of_data stih4xx_dwmac_data = {
357 .fix_mac_speed = stih4xx_fix_retime_src,
358 .setup = sti_dwmac_setup,
359 .init = stix4xx_init,
360 .exit = sti_dwmac_exit,
363 const struct stmmac_of_data stid127_dwmac_data = {
364 .fix_mac_speed = stid127_fix_retime_src,
365 .setup = sti_dwmac_setup,
366 .init = stid127_init,
367 .exit = sti_dwmac_exit,