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 <dm/pinctrl.h>
22 #include <dt-bindings/clock/rk3288-cru.h>
23 #include "designware.h"
25 DECLARE_GLOBAL_DATA_PTR
;
28 * Platform data for the gmac
30 * dw_eth_pdata: Required platform data for designware driver (must be first)
32 struct gmac_rockchip_platdata
{
33 struct dw_eth_pdata dw_eth_pdata
;
39 int (*fix_mac_speed
)(struct dw_eth_dev
*priv
);
40 void (*set_to_rgmii
)(struct gmac_rockchip_platdata
*pdata
);
44 static int gmac_rockchip_ofdata_to_platdata(struct udevice
*dev
)
46 struct gmac_rockchip_platdata
*pdata
= dev_get_platdata(dev
);
48 /* Check the new naming-style first... */
49 pdata
->tx_delay
= dev_read_u32_default(dev
, "tx_delay", -ENOENT
);
50 pdata
->rx_delay
= dev_read_u32_default(dev
, "rx_delay", -ENOENT
);
52 /* ... and fall back to the old naming style or default, if necessary */
53 if (pdata
->tx_delay
== -ENOENT
)
54 pdata
->tx_delay
= dev_read_u32_default(dev
, "tx-delay", 0x30);
55 if (pdata
->rx_delay
== -ENOENT
)
56 pdata
->rx_delay
= dev_read_u32_default(dev
, "rx-delay", 0x10);
58 return designware_eth_ofdata_to_platdata(dev
);
61 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev
*priv
)
63 struct rk3288_grf
*grf
;
66 switch (priv
->phydev
->speed
) {
68 clk
= RK3288_GMAC_CLK_SEL_2_5M
;
71 clk
= RK3288_GMAC_CLK_SEL_25M
;
74 clk
= RK3288_GMAC_CLK_SEL_125M
;
77 debug("Unknown phy speed: %d\n", priv
->phydev
->speed
);
81 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
82 rk_clrsetreg(&grf
->soc_con1
, RK3288_GMAC_CLK_SEL_MASK
, clk
);
87 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev
*priv
)
89 struct rk3368_grf
*grf
;
92 RK3368_GMAC_CLK_SEL_2_5M
= 2 << 4,
93 RK3368_GMAC_CLK_SEL_25M
= 3 << 4,
94 RK3368_GMAC_CLK_SEL_125M
= 0 << 4,
95 RK3368_GMAC_CLK_SEL_MASK
= GENMASK(5, 4),
98 switch (priv
->phydev
->speed
) {
100 clk
= RK3368_GMAC_CLK_SEL_2_5M
;
103 clk
= RK3368_GMAC_CLK_SEL_25M
;
106 clk
= RK3368_GMAC_CLK_SEL_125M
;
109 debug("Unknown phy speed: %d\n", priv
->phydev
->speed
);
113 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
114 rk_clrsetreg(&grf
->soc_con15
, RK3368_GMAC_CLK_SEL_MASK
, clk
);
119 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev
*priv
)
121 struct rk3399_grf_regs
*grf
;
124 switch (priv
->phydev
->speed
) {
126 clk
= RK3399_GMAC_CLK_SEL_2_5M
;
129 clk
= RK3399_GMAC_CLK_SEL_25M
;
132 clk
= RK3399_GMAC_CLK_SEL_125M
;
135 debug("Unknown phy speed: %d\n", priv
->phydev
->speed
);
139 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
140 rk_clrsetreg(&grf
->soc_con5
, RK3399_GMAC_CLK_SEL_MASK
, clk
);
145 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata
*pdata
)
147 struct rk3288_grf
*grf
;
149 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
150 rk_clrsetreg(&grf
->soc_con1
,
151 RK3288_RMII_MODE_MASK
| RK3288_GMAC_PHY_INTF_SEL_MASK
,
152 RK3288_GMAC_PHY_INTF_SEL_RGMII
);
154 rk_clrsetreg(&grf
->soc_con3
,
155 RK3288_RXCLK_DLY_ENA_GMAC_MASK
|
156 RK3288_TXCLK_DLY_ENA_GMAC_MASK
|
157 RK3288_CLK_RX_DL_CFG_GMAC_MASK
|
158 RK3288_CLK_TX_DL_CFG_GMAC_MASK
,
159 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE
|
160 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE
|
161 pdata
->rx_delay
<< RK3288_CLK_RX_DL_CFG_GMAC_SHIFT
|
162 pdata
->tx_delay
<< RK3288_CLK_TX_DL_CFG_GMAC_SHIFT
);
165 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata
*pdata
)
167 struct rk3368_grf
*grf
;
169 RK3368_GMAC_PHY_INTF_SEL_RGMII
= 1 << 9,
170 RK3368_GMAC_PHY_INTF_SEL_MASK
= GENMASK(11, 9),
171 RK3368_RMII_MODE_MASK
= BIT(6),
172 RK3368_RMII_MODE
= BIT(6),
175 RK3368_RXCLK_DLY_ENA_GMAC_MASK
= BIT(15),
176 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE
= 0,
177 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE
= BIT(15),
178 RK3368_TXCLK_DLY_ENA_GMAC_MASK
= BIT(7),
179 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE
= 0,
180 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE
= BIT(7),
181 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT
= 8,
182 RK3368_CLK_RX_DL_CFG_GMAC_MASK
= GENMASK(14, 8),
183 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT
= 0,
184 RK3368_CLK_TX_DL_CFG_GMAC_MASK
= GENMASK(6, 0),
187 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
188 rk_clrsetreg(&grf
->soc_con15
,
189 RK3368_RMII_MODE_MASK
| RK3368_GMAC_PHY_INTF_SEL_MASK
,
190 RK3368_GMAC_PHY_INTF_SEL_RGMII
);
192 rk_clrsetreg(&grf
->soc_con16
,
193 RK3368_RXCLK_DLY_ENA_GMAC_MASK
|
194 RK3368_TXCLK_DLY_ENA_GMAC_MASK
|
195 RK3368_CLK_RX_DL_CFG_GMAC_MASK
|
196 RK3368_CLK_TX_DL_CFG_GMAC_MASK
,
197 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE
|
198 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE
|
199 pdata
->rx_delay
<< RK3368_CLK_RX_DL_CFG_GMAC_SHIFT
|
200 pdata
->tx_delay
<< RK3368_CLK_TX_DL_CFG_GMAC_SHIFT
);
203 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata
*pdata
)
205 struct rk3399_grf_regs
*grf
;
207 grf
= syscon_get_first_range(ROCKCHIP_SYSCON_GRF
);
209 rk_clrsetreg(&grf
->soc_con5
,
210 RK3399_GMAC_PHY_INTF_SEL_MASK
,
211 RK3399_GMAC_PHY_INTF_SEL_RGMII
);
213 rk_clrsetreg(&grf
->soc_con6
,
214 RK3399_RXCLK_DLY_ENA_GMAC_MASK
|
215 RK3399_TXCLK_DLY_ENA_GMAC_MASK
|
216 RK3399_CLK_RX_DL_CFG_GMAC_MASK
|
217 RK3399_CLK_TX_DL_CFG_GMAC_MASK
,
218 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE
|
219 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE
|
220 pdata
->rx_delay
<< RK3399_CLK_RX_DL_CFG_GMAC_SHIFT
|
221 pdata
->tx_delay
<< RK3399_CLK_TX_DL_CFG_GMAC_SHIFT
);
224 static int gmac_rockchip_probe(struct udevice
*dev
)
226 struct gmac_rockchip_platdata
*pdata
= dev_get_platdata(dev
);
227 struct rk_gmac_ops
*ops
=
228 (struct rk_gmac_ops
*)dev_get_driver_data(dev
);
232 ret
= clk_get_by_index(dev
, 0, &clk
);
236 /* Since mac_clk is fed by an external clock we can use 0 here */
237 ret
= clk_set_rate(&clk
, 0);
241 /* Set to RGMII mode */
242 ops
->set_to_rgmii(pdata
);
244 return designware_eth_probe(dev
);
247 static int gmac_rockchip_eth_start(struct udevice
*dev
)
249 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
250 struct dw_eth_dev
*priv
= dev_get_priv(dev
);
251 struct rk_gmac_ops
*ops
=
252 (struct rk_gmac_ops
*)dev_get_driver_data(dev
);
255 ret
= designware_eth_init(priv
, pdata
->enetaddr
);
258 ret
= ops
->fix_mac_speed(priv
);
261 ret
= designware_eth_enable(priv
);
268 const struct eth_ops gmac_rockchip_eth_ops
= {
269 .start
= gmac_rockchip_eth_start
,
270 .send
= designware_eth_send
,
271 .recv
= designware_eth_recv
,
272 .free_pkt
= designware_eth_free_pkt
,
273 .stop
= designware_eth_stop
,
274 .write_hwaddr
= designware_eth_write_hwaddr
,
277 const struct rk_gmac_ops rk3288_gmac_ops
= {
278 .fix_mac_speed
= rk3288_gmac_fix_mac_speed
,
279 .set_to_rgmii
= rk3288_gmac_set_to_rgmii
,
282 const struct rk_gmac_ops rk3368_gmac_ops
= {
283 .fix_mac_speed
= rk3368_gmac_fix_mac_speed
,
284 .set_to_rgmii
= rk3368_gmac_set_to_rgmii
,
287 const struct rk_gmac_ops rk3399_gmac_ops
= {
288 .fix_mac_speed
= rk3399_gmac_fix_mac_speed
,
289 .set_to_rgmii
= rk3399_gmac_set_to_rgmii
,
292 static const struct udevice_id rockchip_gmac_ids
[] = {
293 { .compatible
= "rockchip,rk3288-gmac",
294 .data
= (ulong
)&rk3288_gmac_ops
},
295 { .compatible
= "rockchip,rk3368-gmac",
296 .data
= (ulong
)&rk3368_gmac_ops
},
297 { .compatible
= "rockchip,rk3399-gmac",
298 .data
= (ulong
)&rk3399_gmac_ops
},
302 U_BOOT_DRIVER(eth_gmac_rockchip
) = {
303 .name
= "gmac_rockchip",
305 .of_match
= rockchip_gmac_ids
,
306 .ofdata_to_platdata
= gmac_rockchip_ofdata_to_platdata
,
307 .probe
= gmac_rockchip_probe
,
308 .ops
= &gmac_rockchip_eth_ops
,
309 .priv_auto_alloc_size
= sizeof(struct dw_eth_dev
),
310 .platdata_auto_alloc_size
= sizeof(struct gmac_rockchip_platdata
),
311 .flags
= DM_FLAG_ALLOC_PRIV_DMA
,