global: Move remaining CONFIG_SYS_* to CFG_SYS_*
[platform/kernel/u-boot.git] / drivers / net / dwmac_meson8b.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2021 BayLibre, SAS
4  */
5
6 #include <common.h>
7 #include <asm/io.h>
8 #include <dm.h>
9 #include <phy.h>
10 #include "designware.h"
11 #include <dm/device_compat.h>
12 #include <linux/err.h>
13
14 #define ETH_REG_0               0x0
15 #define ETH_REG_1               0x4
16 #define ETH_REG_2               0x18
17 #define ETH_REG_3               0x1c
18
19 #define GX_ETH_REG_0_PHY_INTF           BIT(0)
20 #define GX_ETH_REG_0_TX_PHASE(x)        (((x) & 3) << 5)
21 #define GX_ETH_REG_0_TX_RATIO(x)        (((x) & 7) << 7)
22 #define GX_ETH_REG_0_PHY_CLK_EN BIT(10)
23 #define GX_ETH_REG_0_INVERT_RMII_CLK    BIT(11)
24 #define GX_ETH_REG_0_CLK_EN             BIT(12)
25
26 #define AXG_ETH_REG_0_PHY_INTF_RGMII    BIT(0)
27 #define AXG_ETH_REG_0_PHY_INTF_RMII     BIT(2)
28 #define AXG_ETH_REG_0_TX_PHASE(x)       (((x) & 3) << 5)
29 #define AXG_ETH_REG_0_TX_RATIO(x)       (((x) & 7) << 7)
30 #define AXG_ETH_REG_0_PHY_CLK_EN        BIT(10)
31 #define AXG_ETH_REG_0_INVERT_RMII_CLK   BIT(11)
32 #define AXG_ETH_REG_0_CLK_EN            BIT(12)
33
34 struct dwmac_meson8b_plat {
35         struct dw_eth_pdata dw_eth_pdata;
36         int (*dwmac_setup)(struct udevice *dev, struct eth_pdata *edata);
37         void *regs;
38 };
39
40 static int dwmac_meson8b_of_to_plat(struct udevice *dev)
41 {
42         struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);
43
44         pdata->regs = (void *)dev_read_addr_index(dev, 1);
45         if ((fdt_addr_t)pdata->regs == FDT_ADDR_T_NONE)
46                 return -EINVAL;
47
48         pdata->dwmac_setup = (void *)dev_get_driver_data(dev);
49         if (!pdata->dwmac_setup)
50                 return -EINVAL;
51
52         return designware_eth_of_to_plat(dev);
53 }
54
55 static int dwmac_setup_axg(struct udevice *dev, struct eth_pdata *edata)
56 {
57         struct dwmac_meson8b_plat *plat = dev_get_plat(dev);
58
59         switch (edata->phy_interface) {
60         case PHY_INTERFACE_MODE_RGMII:
61         case PHY_INTERFACE_MODE_RGMII_ID:
62                 /* Set RGMII mode */
63                 setbits_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
64                                                      AXG_ETH_REG_0_TX_PHASE(1) |
65                                                      AXG_ETH_REG_0_TX_RATIO(4) |
66                                                      AXG_ETH_REG_0_PHY_CLK_EN |
67                                                      AXG_ETH_REG_0_CLK_EN);
68                 break;
69
70         case PHY_INTERFACE_MODE_RGMII_RXID:
71         case PHY_INTERFACE_MODE_RGMII_TXID:
72                 /* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps from DT */
73                 setbits_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
74                                                      AXG_ETH_REG_0_TX_RATIO(4) |
75                                                      AXG_ETH_REG_0_PHY_CLK_EN |
76                                                      AXG_ETH_REG_0_CLK_EN);
77                 break;
78
79         case PHY_INTERFACE_MODE_RMII:
80                 /* Set RMII mode */
81                 out_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
82                                                  AXG_ETH_REG_0_INVERT_RMII_CLK |
83                                                  AXG_ETH_REG_0_CLK_EN);
84                 break;
85         default:
86                 dev_err(dev, "Unsupported PHY mode\n");
87                 return -EINVAL;
88         }
89
90         return 0;
91 }
92
93 static int dwmac_setup_gx(struct udevice *dev, struct eth_pdata *edata)
94 {
95         struct dwmac_meson8b_plat *plat = dev_get_plat(dev);
96
97         switch (edata->phy_interface) {
98         case PHY_INTERFACE_MODE_RGMII:
99         case PHY_INTERFACE_MODE_RGMII_ID:
100                 /* Set RGMII mode */
101                 setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
102                                                      GX_ETH_REG_0_TX_PHASE(1) |
103                                                      GX_ETH_REG_0_TX_RATIO(4) |
104                                                      GX_ETH_REG_0_PHY_CLK_EN |
105                                                      GX_ETH_REG_0_CLK_EN);
106
107                 break;
108
109         case PHY_INTERFACE_MODE_RGMII_RXID:
110         case PHY_INTERFACE_MODE_RGMII_TXID:
111                 /* TOFIX: handle amlogic,tx-delay-ns & rx-internal-delay-ps from DT */
112                 setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
113                                                      GX_ETH_REG_0_TX_RATIO(4) |
114                                                      GX_ETH_REG_0_PHY_CLK_EN |
115                                                      GX_ETH_REG_0_CLK_EN);
116
117                 break;
118
119         case PHY_INTERFACE_MODE_RMII:
120                 /* Set RMII mode */
121                 out_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
122                                                  GX_ETH_REG_0_CLK_EN);
123
124                 if (!IS_ENABLED(CONFIG_MESON_GXBB))
125                         writel(0x10110181, plat->regs + ETH_REG_2);
126
127                 break;
128         default:
129                 dev_err(dev, "Unsupported PHY mode\n");
130                 return -EINVAL;
131         }
132
133         return 0;
134 }
135
136 static int dwmac_meson8b_probe(struct udevice *dev)
137 {
138         struct dwmac_meson8b_plat *pdata = dev_get_plat(dev);
139         struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
140         int ret;
141
142         ret = pdata->dwmac_setup(dev, edata);
143         if (ret)
144                 return ret;
145
146         return designware_eth_probe(dev);
147 }
148
149 static const struct udevice_id dwmac_meson8b_ids[] = {
150         { .compatible = "amlogic,meson-gxbb-dwmac", .data = (ulong)dwmac_setup_gx },
151         { .compatible = "amlogic,meson-g12a-dwmac", .data = (ulong)dwmac_setup_axg },
152         { .compatible = "amlogic,meson-axg-dwmac", .data = (ulong)dwmac_setup_axg },
153         { }
154 };
155
156 U_BOOT_DRIVER(dwmac_meson8b) = {
157         .name           = "dwmac_meson8b",
158         .id             = UCLASS_ETH,
159         .of_match       = dwmac_meson8b_ids,
160         .of_to_plat = dwmac_meson8b_of_to_plat,
161         .probe          = dwmac_meson8b_probe,
162         .ops            = &designware_eth_ops,
163         .priv_auto      = sizeof(struct dw_eth_dev),
164         .plat_auto      = sizeof(struct dwmac_meson8b_plat),
165         .flags          = DM_FLAG_ALLOC_PRIV_DMA,
166 };