Merge branch 'master' of git://www.denx.de/git/u-boot-socfpga
[oweals/u-boot.git] / board / freescale / ls2085aqds / eth.c
1 /*
2  * Copyright 2015 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <netdev.h>
9 #include <asm/io.h>
10 #include <asm/arch/fsl_serdes.h>
11 #include <asm/arch-fsl-lsch3/immap_lsch3.h>
12 #include <fsl_mdio.h>
13 #include <malloc.h>
14 #include <fm_eth.h>
15 #include <fsl-mc/ldpaa_wriop.h>
16
17 #include "../common/qixis.h"
18
19 #include "ls2085aqds_qixis.h"
20
21
22 #ifdef CONFIG_FSL_MC_ENET
23  /* - In LS2085A there are only 16 SERDES lanes, spread across 2 SERDES banks.
24  *   Bank 1 -> Lanes A, B, C, D, E, F, G, H
25  *   Bank 2 -> Lanes A,B, C, D, E, F, G, H
26  */
27
28  /* Mapping of 16 SERDES lanes to LS2085A QDS board slots. A value of '0' here
29   * means that the mapping must be determined dynamically, or that the lane
30   * maps to something other than a board slot.
31   */
32
33 static u8 lane_to_slot_fsm2[] = {
34         0, 0, 0, 0, 0, 0, 0, 0
35 };
36
37 /* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
38  * housed.
39  */
40 static int riser_phy_addr[] = {
41         SGMII_CARD_PORT1_PHY_ADDR,
42         SGMII_CARD_PORT2_PHY_ADDR,
43         SGMII_CARD_PORT3_PHY_ADDR,
44         SGMII_CARD_PORT4_PHY_ADDR,
45 };
46
47 /* Slot2 does not have EMI connections */
48 #define EMI_NONE        0xFFFFFFFF
49 #define EMI1_SLOT1      0
50 #define EMI1_SLOT2      1
51 #define EMI1_SLOT3      2
52 #define EMI1_SLOT4      3
53 #define EMI1_SLOT5      4
54 #define EMI1_SLOT6      5
55 #define EMI2            6
56 #define SFP_TX          1
57
58 static const char * const mdio_names[] = {
59         "LS2085A_QDS_MDIO0",
60         "LS2085A_QDS_MDIO1",
61         "LS2085A_QDS_MDIO2",
62         "LS2085A_QDS_MDIO3",
63         "LS2085A_QDS_MDIO4",
64         "LS2085A_QDS_MDIO5",
65         DEFAULT_WRIOP_MDIO2_NAME,
66 };
67
68 struct ls2085a_qds_mdio {
69         u8 muxval;
70         struct mii_dev *realbus;
71 };
72
73 static const char *ls2085a_qds_mdio_name_for_muxval(u8 muxval)
74 {
75         return mdio_names[muxval];
76 }
77
78 struct mii_dev *mii_dev_for_muxval(u8 muxval)
79 {
80         struct mii_dev *bus;
81         const char *name = ls2085a_qds_mdio_name_for_muxval(muxval);
82
83         if (!name) {
84                 printf("No bus for muxval %x\n", muxval);
85                 return NULL;
86         }
87
88         bus = miiphy_get_dev_by_name(name);
89
90         if (!bus) {
91                 printf("No bus by name %s\n", name);
92                 return NULL;
93         }
94
95         return bus;
96 }
97
98 static void ls2085a_qds_enable_SFP_TX(u8 muxval)
99 {
100         u8 brdcfg9;
101
102         brdcfg9 = QIXIS_READ(brdcfg[9]);
103         brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
104         brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
105         QIXIS_WRITE(brdcfg[9], brdcfg9);
106 }
107
108 static void ls2085a_qds_mux_mdio(u8 muxval)
109 {
110         u8 brdcfg4;
111
112         if (muxval <= 5) {
113                 brdcfg4 = QIXIS_READ(brdcfg[4]);
114                 brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
115                 brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
116                 QIXIS_WRITE(brdcfg[4], brdcfg4);
117         }
118 }
119
120 static int ls2085a_qds_mdio_read(struct mii_dev *bus, int addr,
121                                  int devad, int regnum)
122 {
123         struct ls2085a_qds_mdio *priv = bus->priv;
124
125         ls2085a_qds_mux_mdio(priv->muxval);
126
127         return priv->realbus->read(priv->realbus, addr, devad, regnum);
128 }
129
130 static int ls2085a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
131                                   int regnum, u16 value)
132 {
133         struct ls2085a_qds_mdio *priv = bus->priv;
134
135         ls2085a_qds_mux_mdio(priv->muxval);
136
137         return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
138 }
139
140 static int ls2085a_qds_mdio_reset(struct mii_dev *bus)
141 {
142         struct ls2085a_qds_mdio *priv = bus->priv;
143
144         return priv->realbus->reset(priv->realbus);
145 }
146
147 static int ls2085a_qds_mdio_init(char *realbusname, u8 muxval)
148 {
149         struct ls2085a_qds_mdio *pmdio;
150         struct mii_dev *bus = mdio_alloc();
151
152         if (!bus) {
153                 printf("Failed to allocate ls2085a_qds MDIO bus\n");
154                 return -1;
155         }
156
157         pmdio = malloc(sizeof(*pmdio));
158         if (!pmdio) {
159                 printf("Failed to allocate ls2085a_qds private data\n");
160                 free(bus);
161                 return -1;
162         }
163
164         bus->read = ls2085a_qds_mdio_read;
165         bus->write = ls2085a_qds_mdio_write;
166         bus->reset = ls2085a_qds_mdio_reset;
167         sprintf(bus->name, ls2085a_qds_mdio_name_for_muxval(muxval));
168
169         pmdio->realbus = miiphy_get_dev_by_name(realbusname);
170
171         if (!pmdio->realbus) {
172                 printf("No bus with name %s\n", realbusname);
173                 free(bus);
174                 free(pmdio);
175                 return -1;
176         }
177
178         pmdio->muxval = muxval;
179         bus->priv = pmdio;
180
181         return mdio_register(bus);
182 }
183
184 /*
185  * Initialize the dpmac_info array.
186  *
187  */
188 static void initialize_dpmac_to_slot(void)
189 {
190         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
191         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
192                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
193                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
194         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
195                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
196                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
197
198
199         switch (serdes1_prtcl) {
200         case 0x2A:
201                 printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
202                        serdes1_prtcl);
203                 break;
204         default:
205                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
206                        serdes1_prtcl);
207                 break;
208         }
209
210         switch (serdes2_prtcl) {
211         case 0x07:
212         case 0x08:
213                 printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
214                        serdes2_prtcl);
215                 lane_to_slot_fsm2[0] = EMI1_SLOT4;
216                 lane_to_slot_fsm2[1] = EMI1_SLOT4;
217                 lane_to_slot_fsm2[2] = EMI1_SLOT4;
218                 lane_to_slot_fsm2[3] = EMI1_SLOT4;
219                 /* No MDIO physical connection */
220                 lane_to_slot_fsm2[4] = EMI1_SLOT6;
221                 lane_to_slot_fsm2[5] = EMI1_SLOT6;
222                 lane_to_slot_fsm2[6] = EMI1_SLOT6;
223                 lane_to_slot_fsm2[7] = EMI1_SLOT6;
224                 break;
225         default:
226                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
227                        serdes2_prtcl);
228                 break;
229         }
230 }
231
232 void ls2085a_handle_phy_interface_sgmii(int dpmac_id)
233 {
234         int lane, slot;
235         struct mii_dev *bus;
236         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
237         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
238                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
239                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
240         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
241                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
242                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
243
244         switch (serdes1_prtcl) {
245         }
246
247         switch (serdes2_prtcl) {
248         case 0x07:
249         case 0x08:
250                 lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
251                                                         (dpmac_id - 9));
252                 slot = lane_to_slot_fsm2[lane];
253
254                 switch (++slot) {
255                 case 1:
256                         break;
257                 case 3:
258                         break;
259                 case 4:
260                         /* Slot housing a SGMII riser card? */
261                         wriop_set_phy_address(dpmac_id,
262                                               riser_phy_addr[dpmac_id - 9]);
263                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
264                         bus = mii_dev_for_muxval(EMI1_SLOT4);
265                         wriop_set_mdio(dpmac_id, bus);
266                         dpmac_info[dpmac_id].phydev = phy_connect(
267                                                 dpmac_info[dpmac_id].bus,
268                                                 dpmac_info[dpmac_id].phy_addr,
269                                                 NULL,
270                                                 dpmac_info[dpmac_id].enet_if);
271                         phy_config(dpmac_info[dpmac_id].phydev);
272                 break;
273                 case 5:
274                 break;
275                 case 6:
276                         /* Slot housing a SGMII riser card? */
277                         wriop_set_phy_address(dpmac_id,
278                                               riser_phy_addr[dpmac_id - 13]);
279                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
280                         bus = mii_dev_for_muxval(EMI1_SLOT6);
281                         wriop_set_mdio(dpmac_id, bus);
282                 break;
283         }
284         break;
285         default:
286                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
287                        serdes2_prtcl);
288         break;
289         }
290 }
291 void ls2085a_handle_phy_interface_xsgmii(int i)
292 {
293         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
294         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
295                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
296                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
297
298         switch (serdes1_prtcl) {
299         case 0x2A:
300                 /*
301                  * XFI does not need a PHY to work, but to avoid U-boot use
302                  * default PHY address which is zero to a MAC when it found
303                  * a MAC has no PHY address, we give a PHY address to XFI
304                  * MAC, and should not use a real XAUI PHY address, since
305                  * MDIO can access it successfully, and then MDIO thinks
306                  * the XAUI card is used for the XFI MAC, which will cause
307                  * error.
308                  */
309                 wriop_set_phy_address(i, i + 4);
310                 ls2085a_qds_enable_SFP_TX(SFP_TX);
311
312                 break;
313         default:
314                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
315                        serdes1_prtcl);
316                 break;
317         }
318 }
319 #endif
320
321 int board_eth_init(bd_t *bis)
322 {
323         int error;
324 #ifdef CONFIG_FSL_MC_ENET
325         struct memac_mdio_info *memac_mdio0_info;
326         struct memac_mdio_info *memac_mdio1_info;
327         unsigned int i;
328
329         initialize_dpmac_to_slot();
330
331         memac_mdio0_info = (struct memac_mdio_info *)malloc(
332                                         sizeof(struct memac_mdio_info));
333         memac_mdio0_info->regs =
334                 (struct memac_mdio_controller *)
335                                         CONFIG_SYS_FSL_WRIOP1_MDIO1;
336         memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
337
338         /* Register the real MDIO1 bus */
339         fm_memac_mdio_init(bis, memac_mdio0_info);
340
341         memac_mdio1_info = (struct memac_mdio_info *)malloc(
342                                         sizeof(struct memac_mdio_info));
343         memac_mdio1_info->regs =
344                 (struct memac_mdio_controller *)
345                                         CONFIG_SYS_FSL_WRIOP1_MDIO2;
346         memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
347
348         /* Register the real MDIO2 bus */
349         fm_memac_mdio_init(bis, memac_mdio1_info);
350
351         /* Register the muxing front-ends to the MDIO buses */
352         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
353         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
354         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
355         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
356         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
357         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
358
359         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
360
361         for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
362                 switch (wriop_get_enet_if(i)) {
363                 case PHY_INTERFACE_MODE_QSGMII:
364                         break;
365                 case PHY_INTERFACE_MODE_SGMII:
366                         ls2085a_handle_phy_interface_sgmii(i);
367                         break;
368                 case PHY_INTERFACE_MODE_XGMII:
369                         ls2085a_handle_phy_interface_xsgmii(i);
370                         break;
371                 default:
372                         break;
373                 }
374         }
375
376         error = cpu_eth_init(bis);
377 #endif
378         error = pci_eth_init(bis);
379         return error;
380 }