2 * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
4 * SPDX-License-Identifier: GPL-2.0+
6 * Rockchip GMAC ethernet IP driver for U-Boot
15 #include <asm/arch/periph.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/hardware.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/grf_rk3368.h>
20 #include <asm/arch/grf_rk3399.h>
21 #include <asm/arch/grf_rv1108.h>
22 #include <dm/pinctrl.h>
23 #include <dt-bindings/clock/rk3288-cru.h>
24 #include "designware.h"
26 DECLARE_GLOBAL_DATA_PTR;
29 * Platform data for the gmac
31 * dw_eth_pdata: Required platform data for designware driver (must be first)
33 struct gmac_rockchip_platdata {
34 struct dw_eth_pdata dw_eth_pdata;
41 int (*fix_mac_speed)(struct dw_eth_dev *priv);
42 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
43 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
47 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
49 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
52 string = dev_read_string(dev, "clock_in_out");
53 if (!strcmp(string, "input"))
54 pdata->clock_input = true;
56 pdata->clock_input = false;
58 /* Check the new naming-style first... */
59 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
60 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
62 /* ... and fall back to the old naming style or default, if necessary */
63 if (pdata->tx_delay == -ENOENT)
64 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
65 if (pdata->rx_delay == -ENOENT)
66 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
68 return designware_eth_ofdata_to_platdata(dev);
71 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
73 struct rk3288_grf *grf;
76 switch (priv->phydev->speed) {
78 clk = RK3288_GMAC_CLK_SEL_2_5M;
81 clk = RK3288_GMAC_CLK_SEL_25M;
84 clk = RK3288_GMAC_CLK_SEL_125M;
87 debug("Unknown phy speed: %d\n", priv->phydev->speed);
91 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
92 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
97 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
99 struct rk3368_grf *grf;
102 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
103 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
104 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
105 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
108 switch (priv->phydev->speed) {
110 clk = RK3368_GMAC_CLK_SEL_2_5M;
113 clk = RK3368_GMAC_CLK_SEL_25M;
116 clk = RK3368_GMAC_CLK_SEL_125M;
119 debug("Unknown phy speed: %d\n", priv->phydev->speed);
123 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
124 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
129 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
131 struct rk3399_grf_regs *grf;
134 switch (priv->phydev->speed) {
136 clk = RK3399_GMAC_CLK_SEL_2_5M;
139 clk = RK3399_GMAC_CLK_SEL_25M;
142 clk = RK3399_GMAC_CLK_SEL_125M;
145 debug("Unknown phy speed: %d\n", priv->phydev->speed);
149 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
150 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
155 static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
157 struct rv1108_grf *grf;
160 RV1108_GMAC_SPEED_MASK = BIT(2),
161 RV1108_GMAC_SPEED_10M = 0 << 2,
162 RV1108_GMAC_SPEED_100M = 1 << 2,
163 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
164 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
165 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
168 switch (priv->phydev->speed) {
170 clk = RV1108_GMAC_CLK_SEL_2_5M;
171 speed = RV1108_GMAC_SPEED_10M;
174 clk = RV1108_GMAC_CLK_SEL_25M;
175 speed = RV1108_GMAC_SPEED_100M;
178 debug("Unknown phy speed: %d\n", priv->phydev->speed);
182 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
183 rk_clrsetreg(&grf->gmac_con0,
184 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
190 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
192 struct rk3288_grf *grf;
194 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
195 rk_clrsetreg(&grf->soc_con1,
196 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
197 RK3288_GMAC_PHY_INTF_SEL_RGMII);
199 rk_clrsetreg(&grf->soc_con3,
200 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
201 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
202 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
203 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
204 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
205 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
206 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
207 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
210 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
212 struct rk3368_grf *grf;
214 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
215 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
216 RK3368_RMII_MODE_MASK = BIT(6),
217 RK3368_RMII_MODE = BIT(6),
220 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
221 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
222 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
223 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
224 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
225 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
226 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
227 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
228 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
229 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
232 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
233 rk_clrsetreg(&grf->soc_con15,
234 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
235 RK3368_GMAC_PHY_INTF_SEL_RGMII);
237 rk_clrsetreg(&grf->soc_con16,
238 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
239 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
240 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
241 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
242 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
243 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
244 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
245 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
248 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
250 struct rk3399_grf_regs *grf;
252 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
254 rk_clrsetreg(&grf->soc_con5,
255 RK3399_GMAC_PHY_INTF_SEL_MASK,
256 RK3399_GMAC_PHY_INTF_SEL_RGMII);
258 rk_clrsetreg(&grf->soc_con6,
259 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
260 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
261 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
262 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
263 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
264 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
265 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
266 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
269 static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
271 struct rv1108_grf *grf;
274 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
275 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
278 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
279 rk_clrsetreg(&grf->gmac_con0,
280 RV1108_GMAC_PHY_INTF_SEL_MASK,
281 RV1108_GMAC_PHY_INTF_SEL_RMII);
284 static int gmac_rockchip_probe(struct udevice *dev)
286 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
287 struct rk_gmac_ops *ops =
288 (struct rk_gmac_ops *)dev_get_driver_data(dev);
289 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
290 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
295 ret = clk_get_by_index(dev, 0, &clk);
299 switch (eth_pdata->phy_interface) {
300 case PHY_INTERFACE_MODE_RGMII:
302 * If the gmac clock is from internal pll, need to set and
303 * check the return value for gmac clock at RGMII mode. If
304 * the gmac clock is from external source, the clock rate
305 * is not set, because of it is bypassed.
307 if (!pdata->clock_input) {
308 rate = clk_set_rate(&clk, 125000000);
309 if (rate != 125000000)
313 /* Set to RGMII mode */
314 if (ops->set_to_rgmii)
315 ops->set_to_rgmii(pdata);
320 case PHY_INTERFACE_MODE_RMII:
321 /* The commet is the same as RGMII mode */
322 if (!pdata->clock_input) {
323 rate = clk_set_rate(&clk, 50000000);
324 if (rate != 50000000)
328 /* Set to RMII mode */
329 if (ops->set_to_rmii)
330 ops->set_to_rmii(pdata);
336 debug("NO interface defined!\n");
340 return designware_eth_probe(dev);
343 static int gmac_rockchip_eth_start(struct udevice *dev)
345 struct eth_pdata *pdata = dev_get_platdata(dev);
346 struct dw_eth_dev *priv = dev_get_priv(dev);
347 struct rk_gmac_ops *ops =
348 (struct rk_gmac_ops *)dev_get_driver_data(dev);
351 ret = designware_eth_init(priv, pdata->enetaddr);
354 ret = ops->fix_mac_speed(priv);
357 ret = designware_eth_enable(priv);
364 const struct eth_ops gmac_rockchip_eth_ops = {
365 .start = gmac_rockchip_eth_start,
366 .send = designware_eth_send,
367 .recv = designware_eth_recv,
368 .free_pkt = designware_eth_free_pkt,
369 .stop = designware_eth_stop,
370 .write_hwaddr = designware_eth_write_hwaddr,
373 const struct rk_gmac_ops rk3288_gmac_ops = {
374 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
375 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
378 const struct rk_gmac_ops rk3368_gmac_ops = {
379 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
380 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
383 const struct rk_gmac_ops rk3399_gmac_ops = {
384 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
385 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
388 const struct rk_gmac_ops rv1108_gmac_ops = {
389 .fix_mac_speed = rv1108_set_rmii_speed,
390 .set_to_rmii = rv1108_gmac_set_to_rmii,
393 static const struct udevice_id rockchip_gmac_ids[] = {
394 { .compatible = "rockchip,rk3288-gmac",
395 .data = (ulong)&rk3288_gmac_ops },
396 { .compatible = "rockchip,rk3368-gmac",
397 .data = (ulong)&rk3368_gmac_ops },
398 { .compatible = "rockchip,rk3399-gmac",
399 .data = (ulong)&rk3399_gmac_ops },
400 { .compatible = "rockchip,rv1108-gmac",
401 .data = (ulong)&rv1108_gmac_ops },
405 U_BOOT_DRIVER(eth_gmac_rockchip) = {
406 .name = "gmac_rockchip",
408 .of_match = rockchip_gmac_ids,
409 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
410 .probe = gmac_rockchip_probe,
411 .ops = &gmac_rockchip_eth_ops,
412 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
413 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
414 .flags = DM_FLAG_ALLOC_PRIV_DMA,