blob: 42cb164ad1483cdcea6954ec93e1f55cdc3ce30a [file] [log] [blame]
Peng Fan5721a822022-07-26 16:41:15 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright 2022 NXP
4 */
5
6#include <common.h>
7#include <clk.h>
8#include <cpu_func.h>
9#include <dm.h>
10#include <errno.h>
11#include <eth_phy.h>
12#include <log.h>
13#include <malloc.h>
14#include <memalign.h>
15#include <miiphy.h>
16#include <net.h>
17#include <netdev.h>
18#include <phy.h>
19#include <reset.h>
20#include <wait_bit.h>
21#include <asm/arch/clock.h>
22#include <asm/cache.h>
23#include <asm/gpio.h>
24#include <asm/io.h>
25#include <asm/mach-imx/sys_proto.h>
26#include <linux/delay.h>
27
28#include "dwc_eth_qos.h"
29
30__weak u32 imx_get_eqos_csr_clk(void)
31{
32 return 100 * 1000000;
33}
34
35__weak int imx_eqos_txclk_set_rate(unsigned long rate)
36{
37 return 0;
38}
39
40static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev)
41{
42 return imx_get_eqos_csr_clk();
43}
44
45static int eqos_probe_resources_imx(struct udevice *dev)
46{
47 struct eqos_priv *eqos = dev_get_priv(dev);
48 phy_interface_t interface;
49
50 debug("%s(dev=%p):\n", __func__, dev);
51
52 interface = eqos->config->interface(dev);
53
54 if (interface == PHY_INTERFACE_MODE_NA) {
55 pr_err("Invalid PHY interface\n");
56 return -EINVAL;
57 }
58
59 debug("%s: OK\n", __func__);
60 return 0;
61}
62
63static int eqos_set_tx_clk_speed_imx(struct udevice *dev)
64{
65 struct eqos_priv *eqos = dev_get_priv(dev);
66 ulong rate;
67 int ret;
68
69 debug("%s(dev=%p):\n", __func__, dev);
70
71 switch (eqos->phy->speed) {
72 case SPEED_1000:
73 rate = 125 * 1000 * 1000;
74 break;
75 case SPEED_100:
76 rate = 25 * 1000 * 1000;
77 break;
78 case SPEED_10:
79 rate = 2.5 * 1000 * 1000;
80 break;
81 default:
82 pr_err("invalid speed %d", eqos->phy->speed);
83 return -EINVAL;
84 }
85
86 ret = imx_eqos_txclk_set_rate(rate);
87 if (ret < 0) {
88 pr_err("imx (tx_clk, %lu) failed: %d", rate, ret);
89 return ret;
90 }
91
92 return 0;
93}
94
Peng Fanbf69a7b92022-07-26 16:41:17 +080095static int eqos_get_enetaddr_imx(struct udevice *dev)
96{
97 struct eth_pdata *pdata = dev_get_plat(dev);
98
99 imx_get_mac_from_fuse(dev_seq(dev), pdata->enetaddr);
100
101 return 0;
102}
103
Peng Fan5721a822022-07-26 16:41:15 +0800104static struct eqos_ops eqos_imx_ops = {
105 .eqos_inval_desc = eqos_inval_desc_generic,
106 .eqos_flush_desc = eqos_flush_desc_generic,
107 .eqos_inval_buffer = eqos_inval_buffer_generic,
108 .eqos_flush_buffer = eqos_flush_buffer_generic,
109 .eqos_probe_resources = eqos_probe_resources_imx,
110 .eqos_remove_resources = eqos_null_ops,
111 .eqos_stop_resets = eqos_null_ops,
112 .eqos_start_resets = eqos_null_ops,
113 .eqos_stop_clks = eqos_null_ops,
114 .eqos_start_clks = eqos_null_ops,
115 .eqos_calibrate_pads = eqos_null_ops,
116 .eqos_disable_calibration = eqos_null_ops,
117 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx,
Peng Fanbf69a7b92022-07-26 16:41:17 +0800118 .eqos_get_enetaddr = eqos_get_enetaddr_imx,
119 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx,
Peng Fan5721a822022-07-26 16:41:15 +0800120};
121
122struct eqos_config __maybe_unused eqos_imx_config = {
123 .reg_access_always_ok = false,
124 .mdio_wait = 10,
125 .swr_wait = 50,
126 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
127 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
128 .axi_bus_width = EQOS_AXI_WIDTH_64,
129 .interface = dev_read_phy_mode,
130 .ops = &eqos_imx_ops
131};