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