diff options
Diffstat (limited to 'board/esd/pmc440/pmc440.c')
-rw-r--r-- | board/esd/pmc440/pmc440.c | 165 |
1 files changed, 101 insertions, 64 deletions
diff --git a/board/esd/pmc440/pmc440.c b/board/esd/pmc440/pmc440.c index e86996c55f..062ae67276 100644 --- a/board/esd/pmc440/pmc440.c +++ b/board/esd/pmc440/pmc440.c @@ -12,7 +12,6 @@ * * SPDX-License-Identifier: GPL-2.0+ */ - #include <common.h> #include <libfdt.h> #include <fdt_support.h> @@ -34,14 +33,14 @@ DECLARE_GLOBAL_DATA_PTR; -extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ +extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; extern void __ft_board_setup(void *blob, bd_t *bd); ulong flash_get_size(ulong base, int banknum); -int pci_is_66mhz(void); +static int pci_is_66mhz(void); int is_monarch(void); -int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt); +static int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset, + uchar *buffer, unsigned cnt); struct serial_device *default_serial_console(void) { @@ -58,23 +57,24 @@ struct serial_device *default_serial_console(void) if (((val & 0xf0000000) >> 29) != 7) return &eserial2_device; - ulong scratchreg = in_be32((void*)GPIO0_ISR3L); + ulong scratchreg = in_be32((void *)GPIO0_ISR3L); if (!(scratchreg & 0x80)) { /* mark scratchreg valid */ scratchreg = (scratchreg & 0xffffff00) | 0x80; + i2c_init_all(); + i = bootstrap_eeprom_read(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR, 0x10, buf, 4); if ((i != -1) && (buf[0] == 0x19) && (buf[1] == 0x75)) { scratchreg |= buf[2]; /* bringup delay for console */ - for (delay=0; delay<(1000 * (ulong)buf[3]); delay++) { + for (delay = 0; delay < (1000 * (ulong)buf[3]); delay++) udelay(1000); - } } else scratchreg |= 0x01; - out_be32((void*)GPIO0_ISR3L, scratchreg); + out_be32((void *)GPIO0_ISR3L, scratchreg); } if (scratchreg & 0x01) @@ -93,10 +93,7 @@ int board_early_init_f(void) mtdcr(EBC0_CFGADDR, EBC0_CFG); mtdcr(EBC0_CFGDATA, 0xf8400000); - /* - * Setup the GPIO pins - * TODO: setup GPIOs via CONFIG_SYS_4xx_GPIO_TABLE in board's config file - */ + /* Setup the GPIO pins */ out_be32((void *)GPIO0_OR, 0x40000102); out_be32((void *)GPIO0_TCR, 0x4c90011f); out_be32((void *)GPIO0_OSRL, 0x28051400); @@ -259,7 +256,7 @@ int misc_init_r(void) * USB suff... */ if ((act == NULL || strcmp(act, "host") == 0) && - !(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)){ + !(in_be32((void *)GPIO0_IR) & GPIO0_USB_PRSNT)) { /* SDR Setting */ mfsdr(SDR0_PFC1, sdr0_pfc1); mfsdr(SDR0_USB2D0CR, usb2d0cr); @@ -326,16 +323,16 @@ int misc_init_r(void) mtsdr(SDR0_SRST1, 0x00000000); mtsdr(SDR0_SRST0, 0x00000000); - if (!(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) { + if (!(in_be32((void *)GPIO0_IR) & GPIO0_USB_PRSNT)) { /* enable power on USB socket */ - out_be32((void*)GPIO1_OR, - in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); + out_be32((void *)GPIO1_OR, + in_be32((void *)GPIO1_OR) & ~GPIO1_USB_PWR_N); } printf("USB: Host\n"); } else if ((strcmp(act, "dev") == 0) || - (in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) { + (in_be32((void *)GPIO0_IR) & GPIO0_USB_PRSNT)) { mfsdr(SDR0_USB2PHY0CR, usb2phy0cr); usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; @@ -414,30 +411,31 @@ int misc_init_r(void) #endif /* turn off POST LED */ - out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_POST_N); + out_be32((void *)GPIO1_OR, in_be32((void *)GPIO1_OR) & ~GPIO1_POST_N); /* turn on RUN LED */ - out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) & ~GPIO0_LED_RUN_N); + out_be32((void *)GPIO0_OR, + in_be32((void *)GPIO0_OR) & ~GPIO0_LED_RUN_N); return 0; } int is_monarch(void) { - if (in_be32((void*)GPIO1_IR) & GPIO1_NONMONARCH) + if (in_be32((void *)GPIO1_IR) & GPIO1_NONMONARCH) return 0; return 1; } -int pci_is_66mhz(void) +static int pci_is_66mhz(void) { - if (in_be32((void*)GPIO1_IR) & GPIO1_M66EN) + if (in_be32((void *)GPIO1_IR) & GPIO1_M66EN) return 1; return 0; } -int board_revision(void) +static int board_revision(void) { - return (int)((in_be32((void*)GPIO1_IR) & GPIO1_HWID_MASK) >> 4); + return (int)((in_be32((void *)GPIO1_IR) & GPIO1_HWID_MASK) >> 4); } int checkboard(void) @@ -495,7 +493,7 @@ void pci_target_init(struct pci_controller *hose) out32r(PCIL0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute */ /* - disabled b4 setting */ out32r(PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 Local Address */ - out32r(PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 PCI Low Address */ + out32r(PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 PCI Low Addr */ out32r(PCIL0_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */ out32r(PCIL0_PMM0MA, 0xc0000001); /* 1G + No prefetching, */ /* and enable region */ @@ -532,7 +530,8 @@ void pci_target_init(struct pci_controller *hose) if (is_monarch()) { /* BAR2: map FPGA registers behind system memory at 1GB */ - pci_hose_write_config_dword(hose, 0, PCI_BASE_ADDRESS_2, 0x40000008); + pci_hose_write_config_dword(hose, 0, + PCI_BASE_ADDRESS_2, 0x40000008); } /* @@ -562,10 +561,10 @@ void pci_target_init(struct pci_controller *hose) CONFIG_SYS_PCI_CLASSCODE_NONMONARCH); /* PCI configuration done: release ERREADY */ - out_be32((void*)GPIO1_OR, - in_be32((void*)GPIO1_OR) | GPIO1_PPC_EREADY); - out_be32((void*)GPIO1_TCR, - in_be32((void*)GPIO1_TCR) | GPIO1_PPC_EREADY); + out_be32((void *)GPIO1_OR, + in_be32((void *)GPIO1_OR) | GPIO1_PPC_EREADY); + out_be32((void *)GPIO1_TCR, + in_be32((void *)GPIO1_TCR) | GPIO1_PPC_EREADY); } else { /* Program the board's subsystem id/classcode */ pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID, @@ -595,14 +594,14 @@ void pci_master_init(struct pci_controller *hose) static void wait_for_pci_ready(void) { - if (!(in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY)) { + if (!(in_be32((void *)GPIO1_IR) & GPIO1_PPC_EREADY)) { printf("PCI: Waiting for EREADY (CTRL-C to skip) ... "); while (1) { if (ctrlc()) { puts("abort\n"); break; } - if (in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY) { + if (in_be32((void *)GPIO1_IR) & GPIO1_PPC_EREADY) { printf("done\n"); break; } @@ -641,34 +640,73 @@ int is_pci_host(struct pci_controller *hose) #endif /* defined(CONFIG_PCI) */ #ifdef CONFIG_RESET_PHY_R -void reset_phy(void) +static int pmc440_setup_vsc8601(char *devname, int phy_addr, + unsigned short behavior, unsigned short method) { - char *s; - unsigned short val_method, val_behavior; + /* adjust LED behavior */ + if (miiphy_write(devname, phy_addr, 0x1f, 0x0001) != 0) { + printf("Phy%d: register write access failed\n", phy_addr); + return -1; + } - /* special LED setup for NGCC/CANDES */ - if ((s = getenv("bd_type")) && - ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) { - val_method = 0x0e0a; - val_behavior = 0x0cf2; - } else { - /* PMC440 standard type */ - val_method = 0x0e10; - val_behavior = 0x0cf0; + miiphy_write(devname, phy_addr, 0x11, 0x0010); + miiphy_write(devname, phy_addr, 0x11, behavior); + miiphy_write(devname, phy_addr, 0x10, method); + miiphy_write(devname, phy_addr, 0x1f, 0x0000); + + return 0; +} + +static int pmc440_setup_ksz9031(char *devname, int phy_addr) +{ + unsigned short id1, id2; + + if (miiphy_read(devname, phy_addr, 2, &id1) || + miiphy_read(devname, phy_addr, 3, &id2)) { + printf("Phy%d: cannot read id\n", phy_addr); + return -1; } - if (miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) { - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010); - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior); - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method); - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000); + if ((id1 != 0x0022) || ((id2 & 0xfff0) != 0x1620)) { + printf("Phy%d: unexpected id\n", phy_addr); + return -1; } - if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) { - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010); - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior); - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method); - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000); + /* MMD 2.08: adjust tx_clk pad skew */ + miiphy_write(devname, phy_addr, 0x0d, 2); + miiphy_write(devname, phy_addr, 0x0e, 8); + miiphy_write(devname, phy_addr, 0x0d, 0x4002); + miiphy_write(devname, phy_addr, 0x0e, 0xf | (0x17 << 5)); + + return 0; +} + +void reset_phy(void) +{ + char *s; + unsigned short val_method, val_behavior; + + if (gd->board_type < 4) { + /* special LED setup for NGCC/CANDES */ + s = getenv("bd_type"); + if (s && ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) { + val_method = 0x0e0a; + val_behavior = 0x0cf2; + } else { + /* PMC440 standard type */ + val_method = 0x0e10; + val_behavior = 0x0cf0; + } + + /* boards up to rev. 1.3 use Vitesse VSC8601 phys */ + pmc440_setup_vsc8601("ppc_4xx_eth0", CONFIG_PHY_ADDR, + val_method, val_behavior); + pmc440_setup_vsc8601("ppc_4xx_eth1", CONFIG_PHY1_ADDR, + val_method, val_behavior); + } else { + /* rev. 1.4 uses a Micrel KSZ9031 */ + pmc440_setup_ksz9031("ppc_4xx_eth0", CONFIG_PHY_ADDR); + pmc440_setup_ksz9031("ppc_4xx_eth1", CONFIG_PHY1_ADDR); } } #endif @@ -729,7 +767,6 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, * We must write the address again when changing pages * because the address counter only increments within a page. */ - while (offset < end) { unsigned alen, len; unsigned maxlen; @@ -771,8 +808,8 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, return rcode; } -int bootstrap_eeprom_read (unsigned dev_addr, unsigned offset, - uchar *buffer, unsigned cnt) +static int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset, + uchar *buffer, unsigned cnt) { unsigned end = offset + cnt; unsigned blk_off; @@ -820,10 +857,10 @@ int board_usb_init(int index, enum usb_init_type init) int i; if ((act == NULL || strcmp(act, "host") == 0) && - !(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT)) + !(in_be32((void *)GPIO0_IR) & GPIO0_USB_PRSNT)) /* enable power on USB socket */ - out_be32((void*)GPIO1_OR, - in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); + out_be32((void *)GPIO1_OR, + in_be32((void *)GPIO1_OR) & ~GPIO1_USB_PWR_N); for (i=0; i<1000; i++) udelay(1000); @@ -834,7 +871,7 @@ int board_usb_init(int index, enum usb_init_type init) int usb_board_stop(void) { /* disable power on USB socket */ - out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_USB_PWR_N); + out_be32((void *)GPIO1_OR, in_be32((void *)GPIO1_OR) | GPIO1_USB_PWR_N); return 0; } @@ -858,8 +895,8 @@ void ft_board_setup(void *blob, bd_t *bd) rc = fdt_find_and_setprop(blob, "/plb/pci@1ec000000", "status", "disabled", sizeof("disabled"), 1); if (rc) { - printf("Unable to update property status in PCI node, err=%s\n", - fdt_strerror(rc)); + printf("Unable to update property status in PCI node, "); + printf("err=%s\n", fdt_strerror(rc)); } } } |