blob: 90e7c9100e1211240168877a8c1d08afe51eeac6 [file] [log] [blame]
Priyanka Jainfd45ca02018-11-28 13:04:27 +00001// SPDX-License-Identifier: GPL-2.0+
2/*
Meenakshi Aggarwal8a03b0d2020-12-04 20:17:28 +05303 * Copyright 2018, 2020 NXP
Priyanka Jainfd45ca02018-11-28 13:04:27 +00004 *
5 */
6
Priyanka Jainfd45ca02018-11-28 13:04:27 +00007#include <netdev.h>
Priyanka Jainfd45ca02018-11-28 13:04:27 +00008#include <exports.h>
Priyanka Jainfd45ca02018-11-28 13:04:27 +00009#include <fsl-mc/fsl_mc.h>
Florin Chiculita30a7c132023-05-31 18:02:18 +030010#include "lx2160a.h"
Priyanka Jainfd45ca02018-11-28 13:04:27 +000011
12DECLARE_GLOBAL_DATA_PTR;
13
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +090014int board_eth_init(struct bd_info *bis)
Priyanka Jainfd45ca02018-11-28 13:04:27 +000015{
Priyanka Jainfd45ca02018-11-28 13:04:27 +000016#ifdef CONFIG_PHY_AQUANTIA
17 /*
18 * Export functions to be used by AQ firmware
19 * upload application
20 */
21 gd->jt->strcpy = strcpy;
22 gd->jt->mdelay = mdelay;
23 gd->jt->mdio_get_current_dev = mdio_get_current_dev;
24 gd->jt->phy_find_by_mask = phy_find_by_mask;
25 gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
26 gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
27#endif
28 return pci_eth_init(bis);
29}
30
31#if defined(CONFIG_RESET_PHY_R)
32void reset_phy(void)
33{
34#if defined(CONFIG_FSL_MC_ENET)
35 mc_env_boot();
36#endif
37}
38#endif /* CONFIG_RESET_PHY_R */
Florin Chiculita30a7c132023-05-31 18:02:18 +030039
40static int fdt_get_dpmac_node(void *fdt, int dpmac_id)
41{
42 char dpmac_str[11] = "dpmacs@00";
43 int offset, dpmacs_offset;
44
45 /* get the dpmac offset */
46 dpmacs_offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs");
47 if (dpmacs_offset < 0)
48 dpmacs_offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs");
49
50 if (dpmacs_offset < 0) {
51 printf("dpmacs node not found in device tree\n");
52 return dpmacs_offset;
53 }
54
55 sprintf(dpmac_str, "dpmac@%x", dpmac_id);
56 offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
57 if (offset < 0) {
58 sprintf(dpmac_str, "ethernet@%x", dpmac_id);
59 offset = fdt_subnode_offset(fdt, dpmacs_offset, dpmac_str);
60 if (offset < 0) {
61 printf("dpmac@%x/ethernet@%x node not found in device tree\n",
62 dpmac_id, dpmac_id);
63 return offset;
64 }
65 }
66
67 return offset;
68}
69
70static int fdt_update_phy_addr(void *fdt, int dpmac_id, int phy_addr)
71{
72 char dpmac_str[] = "dpmacs@00";
73 const u32 *phyhandle;
74 int offset;
75 int err;
76
77 /* get the dpmac offset */
78 offset = fdt_get_dpmac_node(fdt, dpmac_id);
79 if (offset < 0)
80 return offset;
81
82 /* get dpmac phy-handle */
83 sprintf(dpmac_str, "dpmac@%x", dpmac_id);
84 phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
85 if (!phyhandle) {
86 printf("%s node not found in device tree\n", dpmac_str);
87 return offset;
88 }
89
90 offset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyhandle));
91 if (offset < 0) {
92 printf("Could not get the ph node offset for dpmac %d\n",
93 dpmac_id);
94 return offset;
95 }
96
97 phy_addr = cpu_to_fdt32(phy_addr);
98 err = fdt_setprop(fdt, offset, "reg", &phy_addr, sizeof(phy_addr));
99 if (err < 0) {
100 printf("Could not set phy node's reg for dpmac %d: %s.\n",
101 dpmac_id, fdt_strerror(err));
102 return err;
103 }
104
105 return 0;
106}
107
108static int fdt_delete_phy_handle(void *fdt, int dpmac_id)
109{
110 const u32 *phyhandle;
111 int offset;
112
113 /* get the dpmac offset */
114 offset = fdt_get_dpmac_node(fdt, dpmac_id);
115 if (offset < 0)
116 return offset;
117
118 /* verify if the node has a phy-handle */
119 phyhandle = (u32 *)fdt_getprop(fdt, offset, "phy-handle", NULL);
120 if (!phyhandle)
121 return 0;
122
123 return fdt_delprop(fdt, offset, "phy-handle");
124}
125
126int fdt_fixup_board_phy_revc(void *fdt)
127{
128 int ret;
129
130 if (get_board_rev() < 'C')
131 return 0;
132
133 /* DPMACs 3,4 have their Aquantia PHYs at new addresses */
134 ret = fdt_update_phy_addr(fdt, 3, AQR113C_PHY_ADDR1);
135 if (ret)
136 return ret;
137
138 ret = fdt_update_phy_addr(fdt, 4, AQR113C_PHY_ADDR2);
139 if (ret)
140 return ret;
141
142 /* There is no PHY for the DPMAC2, so remove the phy-handle */
143 return fdt_delete_phy_handle(fdt, 2);
144}