Prepare v2023.10
[platform/kernel/u-boot.git] / board / freescale / lx2160a / eth_lx2160aqds.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2018-2020 NXP
4  *
5  */
6
7 #include <asm/global_data.h>
8 #include <asm/io.h>
9 #include <exports.h>
10 #include <fsl-mc/fsl_mc.h>
11
12 DECLARE_GLOBAL_DATA_PTR;
13
14 int board_eth_init(struct bd_info *bis)
15 {
16 #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
29         return 0;
30 }
31
32 #if defined(CONFIG_RESET_PHY_R)
33 void reset_phy(void)
34 {
35 #if defined(CONFIG_FSL_MC_ENET)
36         mc_env_boot();
37 #endif
38 }
39 #endif /* CONFIG_RESET_PHY_R */
40
41 #if defined(CONFIG_MULTI_DTB_FIT)
42
43 /* Structure to hold SERDES protocols supported (network interfaces are
44  * described in the DTS).
45  *
46  * @serdes_block: the index of the SERDES block
47  * @serdes_protocol: the decimal value of the protocol supported
48  * @dts_needed: DTS notes describing the current configuration are needed
49  *
50  * When dts_needed is true, the board_fit_config_name_match() function
51  * will try to exactly match the current configuration of the block with a DTS
52  * name provided.
53  */
54 static struct serdes_configuration {
55         u8 serdes_block;
56         u32 serdes_protocol;
57         bool dts_needed;
58 } supported_protocols[] = {
59         /* Serdes block #1 */
60         {1, 3, true},
61         {1, 7, true},
62         {1, 19, true},
63         {1, 20, true},
64
65         /* Serdes block #2 */
66         {2, 2, false},
67         {2, 3, false},
68         {2, 5, false},
69         {2, 11, true},
70
71         /* Serdes block #3 */
72         {3, 2, false},
73         {3, 3, false},
74 };
75
76 #define SUPPORTED_SERDES_PROTOCOLS ARRAY_SIZE(supported_protocols)
77
78 static bool protocol_supported(u8 serdes_block, u32 protocol)
79 {
80         struct serdes_configuration serdes_conf;
81         int i;
82
83         for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
84                 serdes_conf = supported_protocols[i];
85                 if (serdes_conf.serdes_block == serdes_block &&
86                     serdes_conf.serdes_protocol == protocol)
87                         return true;
88         }
89
90         return false;
91 }
92
93 static void get_str_protocol(u8 serdes_block, u32 protocol, char *str)
94 {
95         struct serdes_configuration serdes_conf;
96         int i;
97
98         for (i = 0; i < SUPPORTED_SERDES_PROTOCOLS; i++) {
99                 serdes_conf = supported_protocols[i];
100                 if (serdes_conf.serdes_block == serdes_block &&
101                     serdes_conf.serdes_protocol == protocol) {
102                         if (serdes_conf.dts_needed == true)
103                                 sprintf(str, "%u", protocol);
104                         else
105                                 sprintf(str, "x");
106                         return;
107                 }
108         }
109 }
110
111 int board_fit_config_name_match(const char *name)
112 {
113         struct ccsr_gur *gur = (void *)(CFG_SYS_FSL_GUTS_ADDR);
114         u32 rcw_status = in_le32(&gur->rcwsr[28]);
115         char srds_s1_str[2], srds_s2_str[2], srds_s3_str[2];
116         u32 srds_s1, srds_s2, srds_s3;
117         char expected_dts[100];
118
119         srds_s1 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
120         srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
121
122         srds_s2 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
123         srds_s2 >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
124
125         srds_s3 = rcw_status & FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_MASK;
126         srds_s3 >>= FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_SHIFT;
127
128         /* Check for supported protocols. The default DTS will be used
129          * in this case
130          */
131         if (!protocol_supported(1, srds_s1) ||
132             !protocol_supported(2, srds_s2) ||
133             !protocol_supported(3, srds_s3))
134                 return -1;
135
136         get_str_protocol(1, srds_s1, srds_s1_str);
137         get_str_protocol(2, srds_s2, srds_s2_str);
138         get_str_protocol(3, srds_s3, srds_s3_str);
139
140         sprintf(expected_dts, "fsl-lx2160a-qds-%s-%s-%s",
141                 srds_s1_str, srds_s2_str, srds_s3_str);
142
143         if (!strcmp(name, expected_dts))
144                 return 0;
145
146         return -1;
147 }
148 #endif