3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
6 * by Stefan Roese, DENX Software Engineering, sr@denx.de.
8 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/ppc4xx.h>
13 #include <asm/ppc405.h>
15 #include <fdt_support.h>
16 #include <asm/processor.h>
18 #include <linux/errno.h>
19 #include <asm/ppc4xx-gpio.h>
25 #include <gdsys_fpga.h>
30 DECLARE_GLOBAL_DATA_PTR;
32 #define PHYREG_CONTROL 0
33 #define PHYREG_PAGE_ADDRESS 22
34 #define PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1 16
35 #define PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2 26
36 #define PHYREG_PG2_MAC_SPECIFIC_STATUS_1 17
37 #define PHYREG_PG2_MAC_SPECIFIC_CONTROL 21
39 #define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
40 #define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
41 #define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
42 #define LATCH3_BASE (CONFIG_SYS_LATCH_BASE + 0x300)
45 UNITTYPE_CCD_SWITCH = 1,
53 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
55 static inline void blank_string(int size)
59 for (i = 0; i < size; i++)
61 for (i = 0; i < size; i++)
63 for (i = 0; i < size; i++)
68 * Board early initialization function
73 * Note: DTT has been removed. Please use UCLASS_THERMAL.
80 #ifdef CONFIG_ENV_IS_IN_FLASH
81 /* Monitor protection ON by default */
82 flash_protect(FLAG_PROTECT_SET,
83 -CONFIG_SYS_MONITOR_LEN,
91 static void print_fpga_info(unsigned dev)
96 int fpga_state = get_fpga_state(dev);
99 unsigned hardware_version;
100 unsigned feature_channels;
101 unsigned feature_expansion;
103 FPGA_GET_REG(dev, versions, &versions);
104 FPGA_GET_REG(dev, fpga_version, &fpga_version);
105 FPGA_GET_REG(dev, fpga_features, &fpga_features);
107 printf("FPGA%d: ", dev);
108 if (fpga_state & FPGA_STATE_PLATFORM)
111 if (fpga_state & FPGA_STATE_DONE_FAILED) {
112 printf(" done timed out\n");
116 if (fpga_state & FPGA_STATE_REFLECTION_FAILED) {
117 printf(" refelectione test failed\n");
121 unit_type = (versions & 0xf000) >> 12;
122 hardware_version = versions & 0x000f;
123 feature_channels = fpga_features & 0x007f;
124 feature_expansion = fpga_features & (1<<15);
127 case UNITTYPE_CCD_SWITCH:
128 printf("CCD-Switch");
132 printf("UnitType %d(not supported)", unit_type);
136 switch (hardware_version) {
138 printf(" HW-Ver 1.00\n");
142 printf(" HW-Ver 1.10\n");
146 printf(" HW-Ver %d(not supported)\n",
151 printf(" FPGA V %d.%02d, features:",
152 fpga_version / 100, fpga_version % 100);
154 printf(" %d channel(s)", feature_channels);
156 printf(", expansion %ssupported\n", feature_expansion ? "" : "un");
161 char *s = getenv("serial#");
163 printf("Board: CATCenter Io64\n");
173 int configure_gbit_phy(char *bus, unsigned char addr)
175 unsigned short value;
178 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
180 /* switch to powerdown */
181 if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
184 if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
188 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
190 /* disable SGMII autonegotiation */
191 if (miiphy_write(bus, addr, PHYREG_PG2_MAC_SPECIFIC_CONTROL, 48))
194 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
196 /* switch from powerdown to normal operation */
197 if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
200 if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
203 /* reset phy so settings take effect */
204 if (miiphy_write(bus, addr, PHYREG_CONTROL, 0x9140))
210 printf("Error writing to the PHY addr=%02x\n", addr);
214 int verify_gbit_phy(char *bus, unsigned char addr)
216 unsigned short value;
219 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
221 /* verify SGMII link status */
222 if (miiphy_read(bus, addr, PHYREG_PG2_MAC_SPECIFIC_STATUS_1, &value))
224 if (!(value & (1 << 10)))
230 printf("Error writing to the PHY addr=%02x\n", addr);
234 int last_stage_init(void)
239 char str_phys[] = "Setup PHYs -";
240 char str_serdes[] = "Start SERDES blocks";
241 char str_channels[] = "Start FPGA channels";
242 char str_locks[] = "Verify SERDES locks";
243 char str_hicb[] = "Verify HICB status";
244 char str_status[] = "Verify PHY status -";
245 char slash[] = "\\|/-\\|/-";
250 /* setup Gbit PHYs */
254 struct mii_dev *mdiodev = mdio_alloc();
257 strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII_BUSNAME, MDIO_NAME_LEN);
258 mdiodev->read = bb_miiphy_read;
259 mdiodev->write = bb_miiphy_write;
261 retval = mdio_register(mdiodev);
265 for (k = 0; k < 32; ++k) {
266 configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k);
271 mdiodev = mdio_alloc();
274 strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII1_BUSNAME, MDIO_NAME_LEN);
275 mdiodev->read = bb_miiphy_read;
276 mdiodev->write = bb_miiphy_write;
278 retval = mdio_register(mdiodev);
282 for (k = 0; k < 32; ++k) {
283 configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k);
287 blank_string(strlen(str_phys));
289 /* take fpga serdes blocks out of reset */
292 FPGA_SET_REG(0, quad_serdes_reset, 0);
293 FPGA_SET_REG(1, quad_serdes_reset, 0);
294 blank_string(strlen(str_serdes));
296 /* take channels out of reset */
299 for (fpga = 0; fpga < 2; ++fpga) {
300 for (k = 0; k < 32; ++k)
301 FPGA_SET_REG(fpga, ch[k].config_int, 0);
303 blank_string(strlen(str_channels));
305 /* verify channels serdes lock */
308 for (fpga = 0; fpga < 2; ++fpga) {
309 for (k = 0; k < 32; ++k) {
311 FPGA_GET_REG(fpga, ch[k].status_int, &status);
312 if (!(status & (1 << 4))) {
314 printf("fpga %d channel %d: no serdes lock\n",
318 FPGA_SET_REG(fpga, ch[k].status_int, 0);
321 blank_string(strlen(str_locks));
323 /* verify hicb_status */
325 for (fpga = 0; fpga < 2; ++fpga) {
326 for (k = 0; k < 32; ++k) {
328 FPGA_GET_REG(fpga, hicb_ch[k].status_int, &status);
330 printf("fpga %d hicb %d: hicb status %04x\n",
333 FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0);
336 blank_string(strlen(str_hicb));
338 /* verify phy status */
340 for (k = 0; k < 32; ++k) {
341 if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) {
342 printf("verify baseboard phy %d failed\n", k);
348 for (k = 0; k < 32; ++k) {
349 if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) {
350 printf("verify extensionboard phy %d failed\n", k);
356 blank_string(strlen(str_status));
358 printf("Starting 64 channels %s\n", failed ? "failed" : "ok");
363 void gd405ex_init(void)
367 if (i2c_probe(0x22)) { /* i2c_probe returns 0 on success */
368 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
369 gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
371 pca9698_direction_output(0x22, 39, 1);
375 void gd405ex_set_fpga_reset(unsigned state)
377 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
381 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
382 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
384 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
385 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
388 pca9698_set_value(0x22, 39, state ? 0 : 1);
392 void gd405ex_setup_hw(void)
394 gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED_N, 0);
395 gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED, 1);
398 int gd405ex_get_fpga_done(unsigned fpga)
400 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
403 return in_le16((void *)LATCH3_BASE)
404 & CONFIG_SYS_FPGA_DONE(fpga);
406 return pca9698_get_value(0x22, fpga ? 9 : 8);