1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2018 MediaTek Inc.
5 #include <linux/bitfield.h>
7 #include <linux/mfd/syscon.h>
8 #include <linux/module.h>
10 #include <linux/of_device.h>
11 #include <linux/of_net.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <linux/stmmac.h>
17 #include "stmmac_platform.h"
19 /* Peri Configuration register for mt2712 */
20 #define PERI_ETH_PHY_INTF_SEL 0x418
21 #define PHY_INTF_MII 0
22 #define PHY_INTF_RGMII 1
23 #define PHY_INTF_RMII 4
24 #define RMII_CLK_SRC_RXC BIT(4)
25 #define RMII_CLK_SRC_INTERNAL BIT(5)
27 #define PERI_ETH_DLY 0x428
28 #define ETH_DLY_GTXC_INV BIT(6)
29 #define ETH_DLY_GTXC_ENABLE BIT(5)
30 #define ETH_DLY_GTXC_STAGES GENMASK(4, 0)
31 #define ETH_DLY_TXC_INV BIT(20)
32 #define ETH_DLY_TXC_ENABLE BIT(19)
33 #define ETH_DLY_TXC_STAGES GENMASK(18, 14)
34 #define ETH_DLY_RXC_INV BIT(13)
35 #define ETH_DLY_RXC_ENABLE BIT(12)
36 #define ETH_DLY_RXC_STAGES GENMASK(11, 7)
38 #define PERI_ETH_DLY_FINE 0x800
39 #define ETH_RMII_DLY_TX_INV BIT(2)
40 #define ETH_FINE_DLY_GTXC BIT(1)
41 #define ETH_FINE_DLY_RXC BIT(0)
43 struct mac_delay_struct
{
50 struct mediatek_dwmac_plat_data
{
51 const struct mediatek_dwmac_variant
*variant
;
52 struct mac_delay_struct mac_delay
;
53 struct clk_bulk_data
*clks
;
54 struct device_node
*np
;
55 struct regmap
*peri_regmap
;
57 phy_interface_t phy_mode
;
58 int num_clks_to_config
;
59 bool rmii_clk_from_mac
;
63 struct mediatek_dwmac_variant
{
64 int (*dwmac_set_phy_interface
)(struct mediatek_dwmac_plat_data
*plat
);
65 int (*dwmac_set_delay
)(struct mediatek_dwmac_plat_data
*plat
);
67 /* clock ids to be requested */
68 const char * const *clk_list
;
76 /* list of clocks required for mac */
77 static const char * const mt2712_dwmac_clk_l
[] = {
78 "axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
81 static int mt2712_set_interface(struct mediatek_dwmac_plat_data
*plat
)
83 int rmii_clk_from_mac
= plat
->rmii_clk_from_mac
? RMII_CLK_SRC_INTERNAL
: 0;
84 int rmii_rxc
= plat
->rmii_rxc
? RMII_CLK_SRC_RXC
: 0;
87 /* The clock labeled as "rmii_internal" in mt2712_dwmac_clk_l is needed
88 * only in RMII(when MAC provides the reference clock), and useless for
89 * RGMII/MII/RMII(when PHY provides the reference clock).
90 * num_clks_to_config indicates the real number of clocks should be
91 * configured, equals to (plat->variant->num_clks - 1) in default for all the case,
92 * then +1 for rmii_clk_from_mac case.
94 plat
->num_clks_to_config
= plat
->variant
->num_clks
- 1;
96 /* select phy interface in top control domain */
97 switch (plat
->phy_mode
) {
98 case PHY_INTERFACE_MODE_MII
:
99 intf_val
|= PHY_INTF_MII
;
101 case PHY_INTERFACE_MODE_RMII
:
102 if (plat
->rmii_clk_from_mac
)
103 plat
->num_clks_to_config
++;
104 intf_val
|= (PHY_INTF_RMII
| rmii_rxc
| rmii_clk_from_mac
);
106 case PHY_INTERFACE_MODE_RGMII
:
107 case PHY_INTERFACE_MODE_RGMII_TXID
:
108 case PHY_INTERFACE_MODE_RGMII_RXID
:
109 case PHY_INTERFACE_MODE_RGMII_ID
:
110 intf_val
|= PHY_INTF_RGMII
;
113 dev_err(plat
->dev
, "phy interface not supported\n");
117 regmap_write(plat
->peri_regmap
, PERI_ETH_PHY_INTF_SEL
, intf_val
);
122 static void mt2712_delay_ps2stage(struct mediatek_dwmac_plat_data
*plat
)
124 struct mac_delay_struct
*mac_delay
= &plat
->mac_delay
;
126 switch (plat
->phy_mode
) {
127 case PHY_INTERFACE_MODE_MII
:
128 case PHY_INTERFACE_MODE_RMII
:
129 /* 550ps per stage for MII/RMII */
130 mac_delay
->tx_delay
/= 550;
131 mac_delay
->rx_delay
/= 550;
133 case PHY_INTERFACE_MODE_RGMII
:
134 case PHY_INTERFACE_MODE_RGMII_TXID
:
135 case PHY_INTERFACE_MODE_RGMII_RXID
:
136 case PHY_INTERFACE_MODE_RGMII_ID
:
137 /* 170ps per stage for RGMII */
138 mac_delay
->tx_delay
/= 170;
139 mac_delay
->rx_delay
/= 170;
142 dev_err(plat
->dev
, "phy interface not supported\n");
147 static void mt2712_delay_stage2ps(struct mediatek_dwmac_plat_data
*plat
)
149 struct mac_delay_struct
*mac_delay
= &plat
->mac_delay
;
151 switch (plat
->phy_mode
) {
152 case PHY_INTERFACE_MODE_MII
:
153 case PHY_INTERFACE_MODE_RMII
:
154 /* 550ps per stage for MII/RMII */
155 mac_delay
->tx_delay
*= 550;
156 mac_delay
->rx_delay
*= 550;
158 case PHY_INTERFACE_MODE_RGMII
:
159 case PHY_INTERFACE_MODE_RGMII_TXID
:
160 case PHY_INTERFACE_MODE_RGMII_RXID
:
161 case PHY_INTERFACE_MODE_RGMII_ID
:
162 /* 170ps per stage for RGMII */
163 mac_delay
->tx_delay
*= 170;
164 mac_delay
->rx_delay
*= 170;
167 dev_err(plat
->dev
, "phy interface not supported\n");
172 static int mt2712_set_delay(struct mediatek_dwmac_plat_data
*plat
)
174 struct mac_delay_struct
*mac_delay
= &plat
->mac_delay
;
175 u32 delay_val
= 0, fine_val
= 0;
177 mt2712_delay_ps2stage(plat
);
179 switch (plat
->phy_mode
) {
180 case PHY_INTERFACE_MODE_MII
:
181 delay_val
|= FIELD_PREP(ETH_DLY_TXC_ENABLE
, !!mac_delay
->tx_delay
);
182 delay_val
|= FIELD_PREP(ETH_DLY_TXC_STAGES
, mac_delay
->tx_delay
);
183 delay_val
|= FIELD_PREP(ETH_DLY_TXC_INV
, mac_delay
->tx_inv
);
185 delay_val
|= FIELD_PREP(ETH_DLY_RXC_ENABLE
, !!mac_delay
->rx_delay
);
186 delay_val
|= FIELD_PREP(ETH_DLY_RXC_STAGES
, mac_delay
->rx_delay
);
187 delay_val
|= FIELD_PREP(ETH_DLY_RXC_INV
, mac_delay
->rx_inv
);
189 case PHY_INTERFACE_MODE_RMII
:
190 if (plat
->rmii_clk_from_mac
) {
191 /* case 1: mac provides the rmii reference clock,
192 * and the clock output to TXC pin.
193 * The egress timing can be adjusted by GTXC delay macro circuit.
194 * The ingress timing can be adjusted by TXC delay macro circuit.
196 delay_val
|= FIELD_PREP(ETH_DLY_TXC_ENABLE
, !!mac_delay
->rx_delay
);
197 delay_val
|= FIELD_PREP(ETH_DLY_TXC_STAGES
, mac_delay
->rx_delay
);
198 delay_val
|= FIELD_PREP(ETH_DLY_TXC_INV
, mac_delay
->rx_inv
);
200 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_ENABLE
, !!mac_delay
->tx_delay
);
201 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_STAGES
, mac_delay
->tx_delay
);
202 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_INV
, mac_delay
->tx_inv
);
204 /* case 2: the rmii reference clock is from external phy,
205 * and the property "rmii_rxc" indicates which pin(TXC/RXC)
206 * the reference clk is connected to. The reference clock is a
207 * received signal, so rx_delay/rx_inv are used to indicate
208 * the reference clock timing adjustment
210 if (plat
->rmii_rxc
) {
211 /* the rmii reference clock from outside is connected
212 * to RXC pin, the reference clock will be adjusted
213 * by RXC delay macro circuit.
215 delay_val
|= FIELD_PREP(ETH_DLY_RXC_ENABLE
, !!mac_delay
->rx_delay
);
216 delay_val
|= FIELD_PREP(ETH_DLY_RXC_STAGES
, mac_delay
->rx_delay
);
217 delay_val
|= FIELD_PREP(ETH_DLY_RXC_INV
, mac_delay
->rx_inv
);
219 /* the rmii reference clock from outside is connected
220 * to TXC pin, the reference clock will be adjusted
221 * by TXC delay macro circuit.
223 delay_val
|= FIELD_PREP(ETH_DLY_TXC_ENABLE
, !!mac_delay
->rx_delay
);
224 delay_val
|= FIELD_PREP(ETH_DLY_TXC_STAGES
, mac_delay
->rx_delay
);
225 delay_val
|= FIELD_PREP(ETH_DLY_TXC_INV
, mac_delay
->rx_inv
);
227 /* tx_inv will inverse the tx clock inside mac relateive to
228 * reference clock from external phy,
229 * and this bit is located in the same register with fine-tune
231 if (mac_delay
->tx_inv
)
232 fine_val
= ETH_RMII_DLY_TX_INV
;
235 case PHY_INTERFACE_MODE_RGMII
:
236 case PHY_INTERFACE_MODE_RGMII_TXID
:
237 case PHY_INTERFACE_MODE_RGMII_RXID
:
238 case PHY_INTERFACE_MODE_RGMII_ID
:
239 fine_val
= ETH_FINE_DLY_GTXC
| ETH_FINE_DLY_RXC
;
241 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_ENABLE
, !!mac_delay
->tx_delay
);
242 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_STAGES
, mac_delay
->tx_delay
);
243 delay_val
|= FIELD_PREP(ETH_DLY_GTXC_INV
, mac_delay
->tx_inv
);
245 delay_val
|= FIELD_PREP(ETH_DLY_RXC_ENABLE
, !!mac_delay
->rx_delay
);
246 delay_val
|= FIELD_PREP(ETH_DLY_RXC_STAGES
, mac_delay
->rx_delay
);
247 delay_val
|= FIELD_PREP(ETH_DLY_RXC_INV
, mac_delay
->rx_inv
);
250 dev_err(plat
->dev
, "phy interface not supported\n");
253 regmap_write(plat
->peri_regmap
, PERI_ETH_DLY
, delay_val
);
254 regmap_write(plat
->peri_regmap
, PERI_ETH_DLY_FINE
, fine_val
);
256 mt2712_delay_stage2ps(plat
);
261 static const struct mediatek_dwmac_variant mt2712_gmac_variant
= {
262 .dwmac_set_phy_interface
= mt2712_set_interface
,
263 .dwmac_set_delay
= mt2712_set_delay
,
264 .clk_list
= mt2712_dwmac_clk_l
,
265 .num_clks
= ARRAY_SIZE(mt2712_dwmac_clk_l
),
267 .rx_delay_max
= 17600,
268 .tx_delay_max
= 17600,
271 static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data
*plat
)
273 struct mac_delay_struct
*mac_delay
= &plat
->mac_delay
;
274 u32 tx_delay_ps
, rx_delay_ps
;
277 plat
->peri_regmap
= syscon_regmap_lookup_by_phandle(plat
->np
, "mediatek,pericfg");
278 if (IS_ERR(plat
->peri_regmap
)) {
279 dev_err(plat
->dev
, "Failed to get pericfg syscon\n");
280 return PTR_ERR(plat
->peri_regmap
);
283 err
= of_get_phy_mode(plat
->np
, &plat
->phy_mode
);
285 dev_err(plat
->dev
, "not find phy-mode\n");
289 if (!of_property_read_u32(plat
->np
, "mediatek,tx-delay-ps", &tx_delay_ps
)) {
290 if (tx_delay_ps
< plat
->variant
->tx_delay_max
) {
291 mac_delay
->tx_delay
= tx_delay_ps
;
293 dev_err(plat
->dev
, "Invalid TX clock delay: %dps\n", tx_delay_ps
);
298 if (!of_property_read_u32(plat
->np
, "mediatek,rx-delay-ps", &rx_delay_ps
)) {
299 if (rx_delay_ps
< plat
->variant
->rx_delay_max
) {
300 mac_delay
->rx_delay
= rx_delay_ps
;
302 dev_err(plat
->dev
, "Invalid RX clock delay: %dps\n", rx_delay_ps
);
307 mac_delay
->tx_inv
= of_property_read_bool(plat
->np
, "mediatek,txc-inverse");
308 mac_delay
->rx_inv
= of_property_read_bool(plat
->np
, "mediatek,rxc-inverse");
309 plat
->rmii_rxc
= of_property_read_bool(plat
->np
, "mediatek,rmii-rxc");
310 plat
->rmii_clk_from_mac
= of_property_read_bool(plat
->np
, "mediatek,rmii-clk-from-mac");
315 static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data
*plat
)
317 const struct mediatek_dwmac_variant
*variant
= plat
->variant
;
318 int i
, num
= variant
->num_clks
;
320 plat
->clks
= devm_kcalloc(plat
->dev
, num
, sizeof(*plat
->clks
), GFP_KERNEL
);
324 for (i
= 0; i
< num
; i
++)
325 plat
->clks
[i
].id
= variant
->clk_list
[i
];
327 plat
->num_clks_to_config
= variant
->num_clks
;
329 return devm_clk_bulk_get(plat
->dev
, num
, plat
->clks
);
332 static int mediatek_dwmac_init(struct platform_device
*pdev
, void *priv
)
334 struct mediatek_dwmac_plat_data
*plat
= priv
;
335 const struct mediatek_dwmac_variant
*variant
= plat
->variant
;
338 ret
= dma_set_mask_and_coherent(plat
->dev
, DMA_BIT_MASK(variant
->dma_bit_mask
));
340 dev_err(plat
->dev
, "No suitable DMA available, err = %d\n", ret
);
344 ret
= variant
->dwmac_set_phy_interface(plat
);
346 dev_err(plat
->dev
, "failed to set phy interface, err = %d\n", ret
);
350 ret
= variant
->dwmac_set_delay(plat
);
352 dev_err(plat
->dev
, "failed to set delay value, err = %d\n", ret
);
356 ret
= clk_bulk_prepare_enable(plat
->num_clks_to_config
, plat
->clks
);
358 dev_err(plat
->dev
, "failed to enable clks, err = %d\n", ret
);
362 pm_runtime_enable(&pdev
->dev
);
363 pm_runtime_get_sync(&pdev
->dev
);
368 static void mediatek_dwmac_exit(struct platform_device
*pdev
, void *priv
)
370 struct mediatek_dwmac_plat_data
*plat
= priv
;
372 clk_bulk_disable_unprepare(plat
->num_clks_to_config
, plat
->clks
);
374 pm_runtime_put_sync(&pdev
->dev
);
375 pm_runtime_disable(&pdev
->dev
);
378 static int mediatek_dwmac_probe(struct platform_device
*pdev
)
380 struct mediatek_dwmac_plat_data
*priv_plat
;
381 struct plat_stmmacenet_data
*plat_dat
;
382 struct stmmac_resources stmmac_res
;
385 priv_plat
= devm_kzalloc(&pdev
->dev
, sizeof(*priv_plat
), GFP_KERNEL
);
389 priv_plat
->variant
= of_device_get_match_data(&pdev
->dev
);
390 if (!priv_plat
->variant
) {
391 dev_err(&pdev
->dev
, "Missing dwmac-mediatek variant\n");
395 priv_plat
->dev
= &pdev
->dev
;
396 priv_plat
->np
= pdev
->dev
.of_node
;
398 ret
= mediatek_dwmac_config_dt(priv_plat
);
402 ret
= mediatek_dwmac_clk_init(priv_plat
);
406 ret
= stmmac_get_platform_resources(pdev
, &stmmac_res
);
410 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
411 if (IS_ERR(plat_dat
))
412 return PTR_ERR(plat_dat
);
414 plat_dat
->interface
= priv_plat
->phy_mode
;
415 plat_dat
->has_gmac4
= 1;
416 plat_dat
->has_gmac
= 0;
418 plat_dat
->riwt_off
= 1;
419 plat_dat
->maxmtu
= ETH_DATA_LEN
;
420 plat_dat
->bsp_priv
= priv_plat
;
421 plat_dat
->init
= mediatek_dwmac_init
;
422 plat_dat
->exit
= mediatek_dwmac_exit
;
423 mediatek_dwmac_init(pdev
, priv_plat
);
425 ret
= stmmac_dvr_probe(&pdev
->dev
, plat_dat
, &stmmac_res
);
427 stmmac_remove_config_dt(pdev
, plat_dat
);
434 static const struct of_device_id mediatek_dwmac_match
[] = {
435 { .compatible
= "mediatek,mt2712-gmac",
436 .data
= &mt2712_gmac_variant
},
440 MODULE_DEVICE_TABLE(of
, mediatek_dwmac_match
);
442 static struct platform_driver mediatek_dwmac_driver
= {
443 .probe
= mediatek_dwmac_probe
,
444 .remove
= stmmac_pltfr_remove
,
446 .name
= "dwmac-mediatek",
447 .pm
= &stmmac_pltfr_pm_ops
,
448 .of_match_table
= mediatek_dwmac_match
,
451 module_platform_driver(mediatek_dwmac_driver
);
453 MODULE_AUTHOR("Biao Huang <biao.huang@mediatek.com>");
454 MODULE_DESCRIPTION("MediaTek DWMAC specific glue layer");
455 MODULE_LICENSE("GPL v2");