]> Git Repo - J-u-boot.git/blob - drivers/net/dwc_eth_qos_stm32.c
net: dwc_eth_qos: Constify st, eth-* values parsed out of DT
[J-u-boot.git] / drivers / net / dwc_eth_qos_stm32.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2024, Marek Vasut <[email protected]>
4  *
5  * This is code moved from drivers/net/dwc_eth_qos.c , which is:
6  * Copyright (c) 2016, NVIDIA CORPORATION.
7  */
8
9 #include <common.h>
10 #include <asm/cache.h>
11 #include <asm/gpio.h>
12 #include <asm/io.h>
13 #include <clk.h>
14 #include <cpu_func.h>
15 #include <dm.h>
16 #include <dm/device_compat.h>
17 #include <errno.h>
18 #include <eth_phy.h>
19 #include <log.h>
20 #include <malloc.h>
21 #include <memalign.h>
22 #include <miiphy.h>
23 #include <net.h>
24 #include <netdev.h>
25 #include <phy.h>
26 #include <reset.h>
27 #include <syscon.h>
28 #include <wait_bit.h>
29 #include <linux/bitfield.h>
30 #include <linux/delay.h>
31
32 #include "dwc_eth_qos.h"
33
34 /* SYSCFG registers */
35 #define SYSCFG_PMCSETR          0x04
36 #define SYSCFG_PMCCLRR          0x44
37
38 #define SYSCFG_PMCSETR_ETH_CLK_SEL      BIT(16)
39 #define SYSCFG_PMCSETR_ETH_REF_CLK_SEL  BIT(17)
40
41 #define SYSCFG_PMCSETR_ETH_SELMII       BIT(20)
42
43 #define SYSCFG_PMCSETR_ETH_SEL_MASK     GENMASK(23, 21)
44 #define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0x0
45 #define SYSCFG_PMCSETR_ETH_SEL_RGMII    0x1
46 #define SYSCFG_PMCSETR_ETH_SEL_RMII     0x4
47
48 static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
49 {
50         struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
51
52         if (!CONFIG_IS_ENABLED(CLK))
53                 return 0;
54
55         return clk_get_rate(&eqos->clk_master_bus);
56 }
57
58 static int eqos_start_clks_stm32(struct udevice *dev)
59 {
60         struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
61         int ret;
62
63         if (!CONFIG_IS_ENABLED(CLK))
64                 return 0;
65
66         dev_dbg(dev, "%s:\n", __func__);
67
68         ret = clk_enable(&eqos->clk_master_bus);
69         if (ret < 0) {
70                 dev_err(dev, "clk_enable(clk_master_bus) failed: %d\n", ret);
71                 goto err;
72         }
73
74         ret = clk_enable(&eqos->clk_rx);
75         if (ret < 0) {
76                 dev_err(dev, "clk_enable(clk_rx) failed: %d\n", ret);
77                 goto err_disable_clk_master_bus;
78         }
79
80         ret = clk_enable(&eqos->clk_tx);
81         if (ret < 0) {
82                 dev_err(dev, "clk_enable(clk_tx) failed: %d\n", ret);
83                 goto err_disable_clk_rx;
84         }
85
86         if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
87                 ret = clk_enable(&eqos->clk_ck);
88                 if (ret < 0) {
89                         dev_err(dev, "clk_enable(clk_ck) failed: %d\n", ret);
90                         goto err_disable_clk_tx;
91                 }
92                 eqos->clk_ck_enabled = true;
93         }
94
95         dev_dbg(dev, "%s: OK\n", __func__);
96         return 0;
97
98 err_disable_clk_tx:
99         clk_disable(&eqos->clk_tx);
100 err_disable_clk_rx:
101         clk_disable(&eqos->clk_rx);
102 err_disable_clk_master_bus:
103         clk_disable(&eqos->clk_master_bus);
104 err:
105         dev_dbg(dev, "%s: FAILED: %d\n", __func__, ret);
106
107         return ret;
108 }
109
110 static int eqos_stop_clks_stm32(struct udevice *dev)
111 {
112         struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
113
114         if (!CONFIG_IS_ENABLED(CLK))
115                 return 0;
116
117         dev_dbg(dev, "%s:\n", __func__);
118
119         clk_disable(&eqos->clk_tx);
120         clk_disable(&eqos->clk_rx);
121         clk_disable(&eqos->clk_master_bus);
122
123         dev_dbg(dev, "%s: OK\n", __func__);
124
125         return 0;
126 }
127
128 static int eqos_probe_syscfg_stm32(struct udevice *dev,
129                                    phy_interface_t interface_type)
130 {
131         /* Ethernet 50MHz RMII clock selection. */
132         const bool eth_ref_clk_sel = dev_read_bool(dev, "st,eth-ref-clk-sel");
133         /* Gigabit Ethernet 125MHz clock selection. */
134         const bool eth_clk_sel = dev_read_bool(dev, "st,eth-clk-sel");
135         u8 *syscfg;
136         u32 value;
137
138         syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
139         if (!syscfg)
140                 return -ENODEV;
141
142         switch (interface_type) {
143         case PHY_INTERFACE_MODE_MII:
144                 dev_dbg(dev, "PHY_INTERFACE_MODE_MII\n");
145                 value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
146                                    SYSCFG_PMCSETR_ETH_SEL_GMII_MII);
147                 value |= SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
148                 break;
149         case PHY_INTERFACE_MODE_GMII:
150                 dev_dbg(dev, "PHY_INTERFACE_MODE_GMII\n");
151                 value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
152                                    SYSCFG_PMCSETR_ETH_SEL_GMII_MII);
153                 if (eth_clk_sel)
154                         value |= SYSCFG_PMCSETR_ETH_CLK_SEL;
155                 break;
156         case PHY_INTERFACE_MODE_RMII:
157                 dev_dbg(dev, "PHY_INTERFACE_MODE_RMII\n");
158                 value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
159                                    SYSCFG_PMCSETR_ETH_SEL_RMII);
160                 if (eth_ref_clk_sel)
161                         value |= SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
162                 break;
163         case PHY_INTERFACE_MODE_RGMII:
164         case PHY_INTERFACE_MODE_RGMII_ID:
165         case PHY_INTERFACE_MODE_RGMII_RXID:
166         case PHY_INTERFACE_MODE_RGMII_TXID:
167                 dev_dbg(dev, "PHY_INTERFACE_MODE_RGMII\n");
168                 value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
169                                    SYSCFG_PMCSETR_ETH_SEL_RGMII);
170                 if (eth_clk_sel)
171                         value |= SYSCFG_PMCSETR_ETH_CLK_SEL;
172                 break;
173         default:
174                 dev_dbg(dev, "Do not manage %d interface\n",
175                         interface_type);
176                 /* Do not manage others interfaces */
177                 return -EINVAL;
178         }
179
180         /* clear and set ETH configuration bits */
181         writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
182                SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
183                syscfg + SYSCFG_PMCCLRR);
184         writel(value, syscfg + SYSCFG_PMCSETR);
185
186         return 0;
187 }
188
189 static int eqos_probe_resources_stm32(struct udevice *dev)
190 {
191         struct eqos_priv *eqos = dev_get_priv(dev);
192         phy_interface_t interface;
193         int ret;
194
195         dev_dbg(dev, "%s:\n", __func__);
196
197         interface = eqos->config->interface(dev);
198
199         if (interface == PHY_INTERFACE_MODE_NA) {
200                 dev_err(dev, "Invalid PHY interface\n");
201                 return -EINVAL;
202         }
203
204         ret = eqos_probe_syscfg_stm32(dev, interface);
205         if (ret)
206                 return -EINVAL;
207
208         ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
209         if (ret) {
210                 dev_err(dev, "clk_get_by_name(master_bus) failed: %d\n", ret);
211                 goto err_probe;
212         }
213
214         ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
215         if (ret) {
216                 dev_err(dev, "clk_get_by_name(rx) failed: %d\n", ret);
217                 goto err_probe;
218         }
219
220         ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
221         if (ret) {
222                 dev_err(dev, "clk_get_by_name(tx) failed: %d\n", ret);
223                 goto err_probe;
224         }
225
226         /*  Get ETH_CLK clocks (optional) */
227         ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
228         if (ret)
229                 dev_warn(dev, "No phy clock provided %d\n", ret);
230
231         dev_dbg(dev, "%s: OK\n", __func__);
232
233         return 0;
234
235 err_probe:
236
237         dev_dbg(dev, "%s: returns %d\n", __func__, ret);
238
239         return ret;
240 }
241
242 static int eqos_remove_resources_stm32(struct udevice *dev)
243 {
244         dev_dbg(dev, "%s:\n", __func__);
245
246         return 0;
247 }
248
249 static struct eqos_ops eqos_stm32_ops = {
250         .eqos_inval_desc = eqos_inval_desc_generic,
251         .eqos_flush_desc = eqos_flush_desc_generic,
252         .eqos_inval_buffer = eqos_inval_buffer_generic,
253         .eqos_flush_buffer = eqos_flush_buffer_generic,
254         .eqos_probe_resources = eqos_probe_resources_stm32,
255         .eqos_remove_resources = eqos_remove_resources_stm32,
256         .eqos_stop_resets = eqos_null_ops,
257         .eqos_start_resets = eqos_null_ops,
258         .eqos_stop_clks = eqos_stop_clks_stm32,
259         .eqos_start_clks = eqos_start_clks_stm32,
260         .eqos_calibrate_pads = eqos_null_ops,
261         .eqos_disable_calibration = eqos_null_ops,
262         .eqos_set_tx_clk_speed = eqos_null_ops,
263         .eqos_get_enetaddr = eqos_null_ops,
264         .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
265 };
266
267 struct eqos_config __maybe_unused eqos_stm32mp15_config = {
268         .reg_access_always_ok = false,
269         .mdio_wait = 10000,
270         .swr_wait = 50,
271         .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
272         .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
273         .axi_bus_width = EQOS_AXI_WIDTH_64,
274         .interface = dev_read_phy_mode,
275         .ops = &eqos_stm32_ops
276 };
This page took 0.041054 seconds and 4 git commands to generate.