Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / stmicro / stmmac / dwmac-mediatek.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018 MediaTek Inc.
4  */
5 #include <linux/bitfield.h>
6 #include <linux/io.h>
7 #include <linux/mfd/syscon.h>
8 #include <linux/module.h>
9 #include <linux/of.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>
15
16 #include "stmmac.h"
17 #include "stmmac_platform.h"
18
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)
26
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)
37
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)
42
43 struct mac_delay_struct {
44         u32 tx_delay;
45         u32 rx_delay;
46         bool tx_inv;
47         bool rx_inv;
48 };
49
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;
56         struct device *dev;
57         int phy_mode;
58         bool rmii_rxc;
59 };
60
61 struct mediatek_dwmac_variant {
62         int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat);
63         int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
64
65         /* clock ids to be requested */
66         const char * const *clk_list;
67         int num_clks;
68
69         u32 dma_bit_mask;
70         u32 rx_delay_max;
71         u32 tx_delay_max;
72 };
73
74 /* list of clocks required for mac */
75 static const char * const mt2712_dwmac_clk_l[] = {
76         "axi", "apb", "mac_main", "ptp_ref"
77 };
78
79 static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
80 {
81         int rmii_rxc = plat->rmii_rxc ? RMII_CLK_SRC_RXC : 0;
82         u32 intf_val = 0;
83
84         /* select phy interface in top control domain */
85         switch (plat->phy_mode) {
86         case PHY_INTERFACE_MODE_MII:
87                 intf_val |= PHY_INTF_MII;
88                 break;
89         case PHY_INTERFACE_MODE_RMII:
90                 intf_val |= (PHY_INTF_RMII | rmii_rxc);
91                 break;
92         case PHY_INTERFACE_MODE_RGMII:
93         case PHY_INTERFACE_MODE_RGMII_TXID:
94         case PHY_INTERFACE_MODE_RGMII_RXID:
95         case PHY_INTERFACE_MODE_RGMII_ID:
96                 intf_val |= PHY_INTF_RGMII;
97                 break;
98         default:
99                 dev_err(plat->dev, "phy interface not supported\n");
100                 return -EINVAL;
101         }
102
103         regmap_write(plat->peri_regmap, PERI_ETH_PHY_INTF_SEL, intf_val);
104
105         return 0;
106 }
107
108 static void mt2712_delay_ps2stage(struct mediatek_dwmac_plat_data *plat)
109 {
110         struct mac_delay_struct *mac_delay = &plat->mac_delay;
111
112         switch (plat->phy_mode) {
113         case PHY_INTERFACE_MODE_MII:
114         case PHY_INTERFACE_MODE_RMII:
115                 /* 550ps per stage for MII/RMII */
116                 mac_delay->tx_delay /= 550;
117                 mac_delay->rx_delay /= 550;
118                 break;
119         case PHY_INTERFACE_MODE_RGMII:
120         case PHY_INTERFACE_MODE_RGMII_TXID:
121         case PHY_INTERFACE_MODE_RGMII_RXID:
122         case PHY_INTERFACE_MODE_RGMII_ID:
123                 /* 170ps per stage for RGMII */
124                 mac_delay->tx_delay /= 170;
125                 mac_delay->rx_delay /= 170;
126                 break;
127         default:
128                 dev_err(plat->dev, "phy interface not supported\n");
129                 break;
130         }
131 }
132
133 static int mt2712_set_delay(struct mediatek_dwmac_plat_data *plat)
134 {
135         struct mac_delay_struct *mac_delay = &plat->mac_delay;
136         u32 delay_val = 0, fine_val = 0;
137
138         mt2712_delay_ps2stage(plat);
139
140         switch (plat->phy_mode) {
141         case PHY_INTERFACE_MODE_MII:
142                 delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->tx_delay);
143                 delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->tx_delay);
144                 delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->tx_inv);
145
146                 delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
147                 delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay);
148                 delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv);
149                 break;
150         case PHY_INTERFACE_MODE_RMII:
151                 /* the rmii reference clock is from external phy,
152                  * and the property "rmii_rxc" indicates which pin(TXC/RXC)
153                  * the reference clk is connected to. The reference clock is a
154                  * received signal, so rx_delay/rx_inv are used to indicate
155                  * the reference clock timing adjustment
156                  */
157                 if (plat->rmii_rxc) {
158                         /* the rmii reference clock from outside is connected
159                          * to RXC pin, the reference clock will be adjusted
160                          * by RXC delay macro circuit.
161                          */
162                         delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
163                         delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay);
164                         delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv);
165                 } else {
166                         /* the rmii reference clock from outside is connected
167                          * to TXC pin, the reference clock will be adjusted
168                          * by TXC delay macro circuit.
169                          */
170                         delay_val |= FIELD_PREP(ETH_DLY_TXC_ENABLE, !!mac_delay->rx_delay);
171                         delay_val |= FIELD_PREP(ETH_DLY_TXC_STAGES, mac_delay->rx_delay);
172                         delay_val |= FIELD_PREP(ETH_DLY_TXC_INV, mac_delay->rx_inv);
173                 }
174                 /* tx_inv will inverse the tx clock inside mac relateive to
175                  * reference clock from external phy,
176                  * and this bit is located in the same register with fine-tune
177                  */
178                 if (mac_delay->tx_inv)
179                         fine_val = ETH_RMII_DLY_TX_INV;
180                 break;
181         case PHY_INTERFACE_MODE_RGMII:
182         case PHY_INTERFACE_MODE_RGMII_TXID:
183         case PHY_INTERFACE_MODE_RGMII_RXID:
184         case PHY_INTERFACE_MODE_RGMII_ID:
185                 fine_val = ETH_FINE_DLY_GTXC | ETH_FINE_DLY_RXC;
186
187                 delay_val |= FIELD_PREP(ETH_DLY_GTXC_ENABLE, !!mac_delay->tx_delay);
188                 delay_val |= FIELD_PREP(ETH_DLY_GTXC_STAGES, mac_delay->tx_delay);
189                 delay_val |= FIELD_PREP(ETH_DLY_GTXC_INV, mac_delay->tx_inv);
190
191                 delay_val |= FIELD_PREP(ETH_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
192                 delay_val |= FIELD_PREP(ETH_DLY_RXC_STAGES, mac_delay->rx_delay);
193                 delay_val |= FIELD_PREP(ETH_DLY_RXC_INV, mac_delay->rx_inv);
194                 break;
195         default:
196                 dev_err(plat->dev, "phy interface not supported\n");
197                 return -EINVAL;
198         }
199         regmap_write(plat->peri_regmap, PERI_ETH_DLY, delay_val);
200         regmap_write(plat->peri_regmap, PERI_ETH_DLY_FINE, fine_val);
201
202         return 0;
203 }
204
205 static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
206                 .dwmac_set_phy_interface = mt2712_set_interface,
207                 .dwmac_set_delay = mt2712_set_delay,
208                 .clk_list = mt2712_dwmac_clk_l,
209                 .num_clks = ARRAY_SIZE(mt2712_dwmac_clk_l),
210                 .dma_bit_mask = 33,
211                 .rx_delay_max = 17600,
212                 .tx_delay_max = 17600,
213 };
214
215 static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
216 {
217         struct mac_delay_struct *mac_delay = &plat->mac_delay;
218         u32 tx_delay_ps, rx_delay_ps;
219
220         plat->peri_regmap = syscon_regmap_lookup_by_phandle(plat->np, "mediatek,pericfg");
221         if (IS_ERR(plat->peri_regmap)) {
222                 dev_err(plat->dev, "Failed to get pericfg syscon\n");
223                 return PTR_ERR(plat->peri_regmap);
224         }
225
226         plat->phy_mode = of_get_phy_mode(plat->np);
227         if (plat->phy_mode < 0) {
228                 dev_err(plat->dev, "not find phy-mode\n");
229                 return -EINVAL;
230         }
231
232         if (!of_property_read_u32(plat->np, "mediatek,tx-delay-ps", &tx_delay_ps)) {
233                 if (tx_delay_ps < plat->variant->tx_delay_max) {
234                         mac_delay->tx_delay = tx_delay_ps;
235                 } else {
236                         dev_err(plat->dev, "Invalid TX clock delay: %dps\n", tx_delay_ps);
237                         return -EINVAL;
238                 }
239         }
240
241         if (!of_property_read_u32(plat->np, "mediatek,rx-delay-ps", &rx_delay_ps)) {
242                 if (rx_delay_ps < plat->variant->rx_delay_max) {
243                         mac_delay->rx_delay = rx_delay_ps;
244                 } else {
245                         dev_err(plat->dev, "Invalid RX clock delay: %dps\n", rx_delay_ps);
246                         return -EINVAL;
247                 }
248         }
249
250         mac_delay->tx_inv = of_property_read_bool(plat->np, "mediatek,txc-inverse");
251         mac_delay->rx_inv = of_property_read_bool(plat->np, "mediatek,rxc-inverse");
252         plat->rmii_rxc = of_property_read_bool(plat->np, "mediatek,rmii-rxc");
253
254         return 0;
255 }
256
257 static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat)
258 {
259         const struct mediatek_dwmac_variant *variant = plat->variant;
260         int i, num = variant->num_clks;
261
262         plat->clks = devm_kcalloc(plat->dev, num, sizeof(*plat->clks), GFP_KERNEL);
263         if (!plat->clks)
264                 return -ENOMEM;
265
266         for (i = 0; i < num; i++)
267                 plat->clks[i].id = variant->clk_list[i];
268
269         return devm_clk_bulk_get(plat->dev, num, plat->clks);
270 }
271
272 static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
273 {
274         struct mediatek_dwmac_plat_data *plat = priv;
275         const struct mediatek_dwmac_variant *variant = plat->variant;
276         int ret;
277
278         ret = dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(variant->dma_bit_mask));
279         if (ret) {
280                 dev_err(plat->dev, "No suitable DMA available, err = %d\n", ret);
281                 return ret;
282         }
283
284         ret = variant->dwmac_set_phy_interface(plat);
285         if (ret) {
286                 dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
287                 return ret;
288         }
289
290         ret = variant->dwmac_set_delay(plat);
291         if (ret) {
292                 dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
293                 return ret;
294         }
295
296         ret = clk_bulk_prepare_enable(variant->num_clks, plat->clks);
297         if (ret) {
298                 dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
299                 return ret;
300         }
301
302         pm_runtime_enable(&pdev->dev);
303         pm_runtime_get_sync(&pdev->dev);
304
305         return 0;
306 }
307
308 static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
309 {
310         struct mediatek_dwmac_plat_data *plat = priv;
311         const struct mediatek_dwmac_variant *variant = plat->variant;
312
313         clk_bulk_disable_unprepare(variant->num_clks, plat->clks);
314
315         pm_runtime_put_sync(&pdev->dev);
316         pm_runtime_disable(&pdev->dev);
317 }
318
319 static int mediatek_dwmac_probe(struct platform_device *pdev)
320 {
321         struct mediatek_dwmac_plat_data *priv_plat;
322         struct plat_stmmacenet_data *plat_dat;
323         struct stmmac_resources stmmac_res;
324         int ret;
325
326         priv_plat = devm_kzalloc(&pdev->dev, sizeof(*priv_plat), GFP_KERNEL);
327         if (!priv_plat)
328                 return -ENOMEM;
329
330         priv_plat->variant = of_device_get_match_data(&pdev->dev);
331         if (!priv_plat->variant) {
332                 dev_err(&pdev->dev, "Missing dwmac-mediatek variant\n");
333                 return -EINVAL;
334         }
335
336         priv_plat->dev = &pdev->dev;
337         priv_plat->np = pdev->dev.of_node;
338
339         ret = mediatek_dwmac_config_dt(priv_plat);
340         if (ret)
341                 return ret;
342
343         ret = mediatek_dwmac_clk_init(priv_plat);
344         if (ret)
345                 return ret;
346
347         ret = stmmac_get_platform_resources(pdev, &stmmac_res);
348         if (ret)
349                 return ret;
350
351         plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
352         if (IS_ERR(plat_dat))
353                 return PTR_ERR(plat_dat);
354
355         plat_dat->interface = priv_plat->phy_mode;
356         plat_dat->has_gmac4 = 1;
357         plat_dat->has_gmac = 0;
358         plat_dat->pmt = 0;
359         plat_dat->riwt_off = 1;
360         plat_dat->maxmtu = ETH_DATA_LEN;
361         plat_dat->bsp_priv = priv_plat;
362         plat_dat->init = mediatek_dwmac_init;
363         plat_dat->exit = mediatek_dwmac_exit;
364         mediatek_dwmac_init(pdev, priv_plat);
365
366         ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
367         if (ret) {
368                 stmmac_remove_config_dt(pdev, plat_dat);
369                 return ret;
370         }
371
372         return 0;
373 }
374
375 static const struct of_device_id mediatek_dwmac_match[] = {
376         { .compatible = "mediatek,mt2712-gmac",
377           .data = &mt2712_gmac_variant },
378         { }
379 };
380
381 MODULE_DEVICE_TABLE(of, mediatek_dwmac_match);
382
383 static struct platform_driver mediatek_dwmac_driver = {
384         .probe  = mediatek_dwmac_probe,
385         .remove = stmmac_pltfr_remove,
386         .driver = {
387                 .name           = "dwmac-mediatek",
388                 .pm             = &stmmac_pltfr_pm_ops,
389                 .of_match_table = mediatek_dwmac_match,
390         },
391 };
392 module_platform_driver(mediatek_dwmac_driver);
393
394 MODULE_AUTHOR("Biao Huang <biao.huang@mediatek.com>");
395 MODULE_DESCRIPTION("MediaTek DWMAC specific glue layer");
396 MODULE_LICENSE("GPL v2");