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);