rockchip: Put README image creation commands on one line
[platform/kernel/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          0
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         case 0x49:
214                 printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
215                        serdes2_prtcl);
216                 lane_to_slot_fsm2[0] = EMI1_SLOT4;
217                 lane_to_slot_fsm2[1] = EMI1_SLOT4;
218                 lane_to_slot_fsm2[2] = EMI1_SLOT4;
219                 lane_to_slot_fsm2[3] = EMI1_SLOT4;
220                 /* No MDIO physical connection */
221                 lane_to_slot_fsm2[4] = EMI1_SLOT6;
222                 lane_to_slot_fsm2[5] = EMI1_SLOT6;
223                 lane_to_slot_fsm2[6] = EMI1_SLOT6;
224                 lane_to_slot_fsm2[7] = EMI1_SLOT6;
225                 break;
226         default:
227                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
228                        serdes2_prtcl);
229                 break;
230         }
231 }
232
233 void ls2085a_handle_phy_interface_sgmii(int dpmac_id)
234 {
235         int lane, slot;
236         struct mii_dev *bus;
237         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
238         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
239                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
240                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
241         int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
242                                 FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
243                 >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
244
245         switch (serdes1_prtcl) {
246         }
247
248         switch (serdes2_prtcl) {
249         case 0x07:
250         case 0x08:
251         case 0x49:
252                 lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
253                                                         (dpmac_id - 9));
254                 slot = lane_to_slot_fsm2[lane];
255
256                 switch (++slot) {
257                 case 1:
258                         break;
259                 case 3:
260                         break;
261                 case 4:
262                         /* Slot housing a SGMII riser card? */
263                         wriop_set_phy_address(dpmac_id,
264                                               riser_phy_addr[dpmac_id - 9]);
265                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
266                         bus = mii_dev_for_muxval(EMI1_SLOT4);
267                         wriop_set_mdio(dpmac_id, bus);
268                         dpmac_info[dpmac_id].phydev = phy_connect(
269                                                 dpmac_info[dpmac_id].bus,
270                                                 dpmac_info[dpmac_id].phy_addr,
271                                                 NULL,
272                                                 dpmac_info[dpmac_id].enet_if);
273                         phy_config(dpmac_info[dpmac_id].phydev);
274                 break;
275                 case 5:
276                 break;
277                 case 6:
278                         /* Slot housing a SGMII riser card? */
279                         wriop_set_phy_address(dpmac_id,
280                                               riser_phy_addr[dpmac_id - 13]);
281                         dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
282                         bus = mii_dev_for_muxval(EMI1_SLOT6);
283                         wriop_set_mdio(dpmac_id, bus);
284                 break;
285         }
286         break;
287         default:
288                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
289                        serdes2_prtcl);
290         break;
291         }
292 }
293 void ls2085a_handle_phy_interface_xsgmii(int i)
294 {
295         struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
296         int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
297                                 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
298                 >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
299
300         switch (serdes1_prtcl) {
301         case 0x2A:
302                 /*
303                  * XFI does not need a PHY to work, but to avoid U-boot use
304                  * default PHY address which is zero to a MAC when it found
305                  * a MAC has no PHY address, we give a PHY address to XFI
306                  * MAC, and should not use a real XAUI PHY address, since
307                  * MDIO can access it successfully, and then MDIO thinks
308                  * the XAUI card is used for the XFI MAC, which will cause
309                  * error.
310                  */
311                 wriop_set_phy_address(i, i + 4);
312                 ls2085a_qds_enable_SFP_TX(SFP_TX);
313
314                 break;
315         default:
316                 printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
317                        serdes1_prtcl);
318                 break;
319         }
320 }
321 #endif
322
323 int board_eth_init(bd_t *bis)
324 {
325         int error;
326 #ifdef CONFIG_FSL_MC_ENET
327         struct memac_mdio_info *memac_mdio0_info;
328         struct memac_mdio_info *memac_mdio1_info;
329         unsigned int i;
330
331         initialize_dpmac_to_slot();
332
333         memac_mdio0_info = (struct memac_mdio_info *)malloc(
334                                         sizeof(struct memac_mdio_info));
335         memac_mdio0_info->regs =
336                 (struct memac_mdio_controller *)
337                                         CONFIG_SYS_FSL_WRIOP1_MDIO1;
338         memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
339
340         /* Register the real MDIO1 bus */
341         fm_memac_mdio_init(bis, memac_mdio0_info);
342
343         memac_mdio1_info = (struct memac_mdio_info *)malloc(
344                                         sizeof(struct memac_mdio_info));
345         memac_mdio1_info->regs =
346                 (struct memac_mdio_controller *)
347                                         CONFIG_SYS_FSL_WRIOP1_MDIO2;
348         memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
349
350         /* Register the real MDIO2 bus */
351         fm_memac_mdio_init(bis, memac_mdio1_info);
352
353         /* Register the muxing front-ends to the MDIO buses */
354         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
355         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
356         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
357         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
358         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
359         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
360
361         ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
362
363         for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
364                 switch (wriop_get_enet_if(i)) {
365                 case PHY_INTERFACE_MODE_QSGMII:
366                         break;
367                 case PHY_INTERFACE_MODE_SGMII:
368                         ls2085a_handle_phy_interface_sgmii(i);
369                         break;
370                 case PHY_INTERFACE_MODE_XGMII:
371                         ls2085a_handle_phy_interface_xsgmii(i);
372                         break;
373                 default:
374                         break;
375                 }
376         }
377
378         error = cpu_eth_init(bis);
379 #endif
380         error = pci_eth_init(bis);
381         return error;
382 }