]> git.sur5r.net Git - u-boot/blob - board/gdsys/mpc8308/hrcon.c
Remove unnecessary instances of DECLARE_GLOBAL_DATA_PTR
[u-boot] / board / gdsys / mpc8308 / hrcon.c
1 /*
2  * (C) Copyright 2014
3  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <hwconfig.h>
10 #include <i2c.h>
11 #include <spi.h>
12 #include <linux/libfdt.h>
13 #include <fdt_support.h>
14 #include <pci.h>
15 #include <mpc83xx.h>
16 #include <fsl_esdhc.h>
17 #include <asm/io.h>
18 #include <asm/fsl_serdes.h>
19 #include <asm/fsl_mpc83xx_serdes.h>
20
21 #include "mpc8308.h"
22
23 #include <gdsys_fpga.h>
24
25 #include "../common/ioep-fpga.h"
26 #include "../common/osd.h"
27 #include "../common/mclink.h"
28 #include "../common/phy.h"
29 #include "../common/fanctrl.h"
30
31 #include <pca953x.h>
32 #include <pca9698.h>
33
34 #include <miiphy.h>
35
36 #define MAX_MUX_CHANNELS 2
37
38 enum {
39         MCFPGA_DONE = 1 << 0,
40         MCFPGA_INIT_N = 1 << 1,
41         MCFPGA_PROGRAM_N = 1 << 2,
42         MCFPGA_UPDATE_ENABLE_N = 1 << 3,
43         MCFPGA_RESET_N = 1 << 4,
44 };
45
46 enum {
47         GPIO_MDC = 1 << 14,
48         GPIO_MDIO = 1 << 15,
49 };
50
51 unsigned int mclink_fpgacount;
52 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
53
54 struct {
55         u8 bus;
56         u8 addr;
57 } hrcon_fans[] = CONFIG_HRCON_FANS;
58
59 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
60 {
61         int res;
62
63         switch (fpga) {
64         case 0:
65                 out_le16(reg, data);
66                 break;
67         default:
68                 res = mclink_send(fpga - 1, regoff, data);
69                 if (res < 0) {
70                         printf("mclink_send reg %02lx data %04x returned %d\n",
71                                regoff, data, res);
72                         return res;
73                 }
74                 break;
75         }
76
77         return 0;
78 }
79
80 int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
81 {
82         int res;
83
84         switch (fpga) {
85         case 0:
86                 *data = in_le16(reg);
87                 break;
88         default:
89                 if (fpga > mclink_fpgacount)
90                         return -EINVAL;
91                 res = mclink_receive(fpga - 1, regoff, data);
92                 if (res < 0) {
93                         printf("mclink_receive reg %02lx returned %d\n",
94                                regoff, res);
95                         return res;
96                 }
97         }
98
99         return 0;
100 }
101
102 int checkboard(void)
103 {
104         char *s = env_get("serial#");
105         bool hw_type_cat = pca9698_get_value(0x20, 20);
106
107         puts("Board: ");
108
109         printf("HRCon %s", hw_type_cat ? "CAT" : "Fiber");
110
111         if (s != NULL) {
112                 puts(", serial# ");
113                 puts(s);
114         }
115
116         puts("\n");
117
118         return 0;
119 }
120
121 int last_stage_init(void)
122 {
123         int slaves;
124         unsigned int k;
125         unsigned int mux_ch;
126         unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
127         u16 fpga_features;
128         bool hw_type_cat = pca9698_get_value(0x20, 20);
129         bool ch0_rgmii2_present = false;
130
131         FPGA_GET_REG(0, fpga_features, &fpga_features);
132
133         /* Turn on Parade DP501 */
134         pca9698_direction_output(0x20, 10, 1);
135         pca9698_direction_output(0x20, 11, 1);
136
137         ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
138
139         /* wait for FPGA done, then reset FPGA */
140         for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
141                 unsigned int ctr = 0;
142
143                 if (i2c_probe(mclink_controllers[k]))
144                         continue;
145
146                 while (!(pca953x_get_val(mclink_controllers[k])
147                        & MCFPGA_DONE)) {
148                         udelay(100000);
149                         if (ctr++ > 5) {
150                                 printf("no done for mclink_controller %d\n", k);
151                                 break;
152                         }
153                 }
154
155                 pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
156                 pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
157                 udelay(10);
158                 pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
159                                 MCFPGA_RESET_N);
160         }
161
162         if (hw_type_cat) {
163                 int retval;
164                 struct mii_dev *mdiodev = mdio_alloc();
165                 if (!mdiodev)
166                         return -ENOMEM;
167                 strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
168                 mdiodev->read = bb_miiphy_read;
169                 mdiodev->write = bb_miiphy_write;
170
171                 retval = mdio_register(mdiodev);
172                 if (retval < 0)
173                         return retval;
174                 for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
175                         if ((mux_ch == 1) && !ch0_rgmii2_present)
176                                 continue;
177
178                         setup_88e1514(bb_miiphy_buses[0].name, mux_ch);
179                 }
180         }
181
182         /* give slave-PLLs and Parade DP501 some time to be up and running */
183         udelay(500000);
184
185         mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
186         slaves = mclink_probe();
187         mclink_fpgacount = 0;
188
189         ioep_fpga_print_info(0);
190         osd_probe(0);
191 #ifdef CONFIG_SYS_OSD_DH
192         osd_probe(4);
193 #endif
194
195         if (slaves <= 0)
196                 return 0;
197
198         mclink_fpgacount = slaves;
199
200         for (k = 1; k <= slaves; ++k) {
201                 FPGA_GET_REG(k, fpga_features, &fpga_features);
202
203                 ioep_fpga_print_info(k);
204                 osd_probe(k);
205 #ifdef CONFIG_SYS_OSD_DH
206                 osd_probe(k + 4);
207 #endif
208                 if (hw_type_cat) {
209                         int retval;
210                         struct mii_dev *mdiodev = mdio_alloc();
211                         if (!mdiodev)
212                                 return -ENOMEM;
213                         strncpy(mdiodev->name, bb_miiphy_buses[k].name,
214                                 MDIO_NAME_LEN);
215                         mdiodev->read = bb_miiphy_read;
216                         mdiodev->write = bb_miiphy_write;
217
218                         retval = mdio_register(mdiodev);
219                         if (retval < 0)
220                                 return retval;
221                         setup_88e1514(bb_miiphy_buses[k].name, 0);
222                 }
223         }
224
225         for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) {
226                 i2c_set_bus_num(hrcon_fans[k].bus);
227                 init_fan_controller(hrcon_fans[k].addr);
228         }
229
230         return 0;
231 }
232
233 /*
234  * provide access to fpga gpios and controls (for I2C bitbang)
235  * (these may look all too simple but make iocon.h much more readable)
236  */
237 void fpga_gpio_set(unsigned int bus, int pin)
238 {
239         FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin);
240 }
241
242 void fpga_gpio_clear(unsigned int bus, int pin)
243 {
244         FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin);
245 }
246
247 int fpga_gpio_get(unsigned int bus, int pin)
248 {
249         u16 val;
250
251         FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val);
252
253         return val & pin;
254 }
255
256 void fpga_control_set(unsigned int bus, int pin)
257 {
258         u16 val;
259
260         FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
261         FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin);
262 }
263
264 void fpga_control_clear(unsigned int bus, int pin)
265 {
266         u16 val;
267
268         FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val);
269         FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin);
270 }
271
272 void mpc8308_init(void)
273 {
274         pca9698_direction_output(0x20, 4, 1);
275 }
276
277 void mpc8308_set_fpga_reset(unsigned state)
278 {
279         pca9698_set_value(0x20, 4, state ? 0 : 1);
280 }
281
282 void mpc8308_setup_hw(void)
283 {
284         immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
285
286         /*
287          * set "startup-finished"-gpios
288          */
289         setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
290         setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
291 }
292
293 int mpc8308_get_fpga_done(unsigned fpga)
294 {
295         return pca9698_get_value(0x20, 19);
296 }
297
298 #ifdef CONFIG_FSL_ESDHC
299 int board_mmc_init(bd_t *bd)
300 {
301         immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
302         sysconf83xx_t *sysconf = &immr->sysconf;
303
304         /* Enable cache snooping in eSDHC system configuration register */
305         out_be32(&sysconf->sdhccr, 0x02000000);
306
307         return fsl_esdhc_mmc_init(bd);
308 }
309 #endif
310
311 static struct pci_region pcie_regions_0[] = {
312         {
313                 .bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
314                 .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
315                 .size = CONFIG_SYS_PCIE1_MEM_SIZE,
316                 .flags = PCI_REGION_MEM,
317         },
318         {
319                 .bus_start = CONFIG_SYS_PCIE1_IO_BASE,
320                 .phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
321                 .size = CONFIG_SYS_PCIE1_IO_SIZE,
322                 .flags = PCI_REGION_IO,
323         },
324 };
325
326 void pci_init_board(void)
327 {
328         immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
329         sysconf83xx_t *sysconf = &immr->sysconf;
330         law83xx_t *pcie_law = sysconf->pcielaw;
331         struct pci_region *pcie_reg[] = { pcie_regions_0 };
332
333         fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
334                          FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
335
336         /* Deassert the resets in the control register */
337         out_be32(&sysconf->pecr1, 0xE0008000);
338         udelay(2000);
339
340         /* Configure PCI Express Local Access Windows */
341         out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
342         out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
343
344         mpc83xx_pcie_init(1, pcie_reg);
345 }
346
347 ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
348 {
349         info->portwidth = FLASH_CFI_16BIT;
350         info->chipwidth = FLASH_CFI_BY16;
351         info->interface = FLASH_CFI_X16;
352         return 1;
353 }
354
355 #if defined(CONFIG_OF_BOARD_SETUP)
356 int ft_board_setup(void *blob, bd_t *bd)
357 {
358         ft_cpu_setup(blob, bd);
359         fsl_fdt_fixup_dr_usb(blob, bd);
360         fdt_fixup_esdhc(blob, bd);
361
362         return 0;
363 }
364 #endif
365
366 /*
367  * FPGA MII bitbang implementation
368  */
369
370 struct fpga_mii {
371         unsigned fpga;
372         int mdio;
373 } fpga_mii[] = {
374         { 0, 1},
375         { 1, 1},
376         { 2, 1},
377         { 3, 1},
378 };
379
380 static int mii_dummy_init(struct bb_miiphy_bus *bus)
381 {
382         return 0;
383 }
384
385 static int mii_mdio_active(struct bb_miiphy_bus *bus)
386 {
387         struct fpga_mii *fpga_mii = bus->priv;
388
389         if (fpga_mii->mdio)
390                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
391         else
392                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
393
394         return 0;
395 }
396
397 static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
398 {
399         struct fpga_mii *fpga_mii = bus->priv;
400
401         FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
402
403         return 0;
404 }
405
406 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
407 {
408         struct fpga_mii *fpga_mii = bus->priv;
409
410         if (v)
411                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
412         else
413                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
414
415         fpga_mii->mdio = v;
416
417         return 0;
418 }
419
420 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
421 {
422         u16 gpio;
423         struct fpga_mii *fpga_mii = bus->priv;
424
425         FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
426
427         *v = ((gpio & GPIO_MDIO) != 0);
428
429         return 0;
430 }
431
432 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
433 {
434         struct fpga_mii *fpga_mii = bus->priv;
435
436         if (v)
437                 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
438         else
439                 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
440
441         return 0;
442 }
443
444 static int mii_delay(struct bb_miiphy_bus *bus)
445 {
446         udelay(1);
447
448         return 0;
449 }
450
451 struct bb_miiphy_bus bb_miiphy_buses[] = {
452         {
453                 .name = "board0",
454                 .init = mii_dummy_init,
455                 .mdio_active = mii_mdio_active,
456                 .mdio_tristate = mii_mdio_tristate,
457                 .set_mdio = mii_set_mdio,
458                 .get_mdio = mii_get_mdio,
459                 .set_mdc = mii_set_mdc,
460                 .delay = mii_delay,
461                 .priv = &fpga_mii[0],
462         },
463         {
464                 .name = "board1",
465                 .init = mii_dummy_init,
466                 .mdio_active = mii_mdio_active,
467                 .mdio_tristate = mii_mdio_tristate,
468                 .set_mdio = mii_set_mdio,
469                 .get_mdio = mii_get_mdio,
470                 .set_mdc = mii_set_mdc,
471                 .delay = mii_delay,
472                 .priv = &fpga_mii[1],
473         },
474         {
475                 .name = "board2",
476                 .init = mii_dummy_init,
477                 .mdio_active = mii_mdio_active,
478                 .mdio_tristate = mii_mdio_tristate,
479                 .set_mdio = mii_set_mdio,
480                 .get_mdio = mii_get_mdio,
481                 .set_mdc = mii_set_mdc,
482                 .delay = mii_delay,
483                 .priv = &fpga_mii[2],
484         },
485         {
486                 .name = "board3",
487                 .init = mii_dummy_init,
488                 .mdio_active = mii_mdio_active,
489                 .mdio_tristate = mii_mdio_tristate,
490                 .set_mdio = mii_set_mdio,
491                 .get_mdio = mii_get_mdio,
492                 .set_mdc = mii_set_mdc,
493                 .delay = mii_delay,
494                 .priv = &fpga_mii[3],
495         },
496 };
497
498 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
499                           sizeof(bb_miiphy_buses[0]);