提交 e634c9dc 编写于 作者: M Matthias Fuchs 提交者: Stefan Roese

ppc4xx: add support for new PMC440 revision with cleanup

This patch adds support for the new PMC440 hardware revision 1.4.
The board now uses Micrel KSZ9031 phys.

Add missing i2c initialization before reading bootstrap eeprom.

Fix a couple of coding style issues.

Make local functions static.
Signed-off-by: NMatthias Fuchs <matthias.fuchs@esd.eu>
Signed-off-by: NStefan Roese <sr@denx.de>
上级 adcdeacc
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* *
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
#include <common.h> #include <common.h>
#include <libfdt.h> #include <libfdt.h>
#include <fdt_support.h> #include <fdt_support.h>
...@@ -34,14 +33,14 @@ ...@@ -34,14 +33,14 @@
DECLARE_GLOBAL_DATA_PTR; 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); extern void __ft_board_setup(void *blob, bd_t *bd);
ulong flash_get_size(ulong base, int banknum); ulong flash_get_size(ulong base, int banknum);
int pci_is_66mhz(void); static int pci_is_66mhz(void);
int is_monarch(void); int is_monarch(void);
int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset, static int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt); uchar *buffer, unsigned cnt);
struct serial_device *default_serial_console(void) struct serial_device *default_serial_console(void)
{ {
...@@ -58,23 +57,24 @@ struct serial_device *default_serial_console(void) ...@@ -58,23 +57,24 @@ struct serial_device *default_serial_console(void)
if (((val & 0xf0000000) >> 29) != 7) if (((val & 0xf0000000) >> 29) != 7)
return &eserial2_device; return &eserial2_device;
ulong scratchreg = in_be32((void*)GPIO0_ISR3L); ulong scratchreg = in_be32((void *)GPIO0_ISR3L);
if (!(scratchreg & 0x80)) { if (!(scratchreg & 0x80)) {
/* mark scratchreg valid */ /* mark scratchreg valid */
scratchreg = (scratchreg & 0xffffff00) | 0x80; scratchreg = (scratchreg & 0xffffff00) | 0x80;
i2c_init_all();
i = bootstrap_eeprom_read(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR, i = bootstrap_eeprom_read(CONFIG_SYS_I2C_BOOT_EEPROM_ADDR,
0x10, buf, 4); 0x10, buf, 4);
if ((i != -1) && (buf[0] == 0x19) && (buf[1] == 0x75)) { if ((i != -1) && (buf[0] == 0x19) && (buf[1] == 0x75)) {
scratchreg |= buf[2]; scratchreg |= buf[2];
/* bringup delay for console */ /* bringup delay for console */
for (delay=0; delay<(1000 * (ulong)buf[3]); delay++) { for (delay = 0; delay < (1000 * (ulong)buf[3]); delay++)
udelay(1000); udelay(1000);
}
} else } else
scratchreg |= 0x01; scratchreg |= 0x01;
out_be32((void*)GPIO0_ISR3L, scratchreg); out_be32((void *)GPIO0_ISR3L, scratchreg);
} }
if (scratchreg & 0x01) if (scratchreg & 0x01)
...@@ -93,10 +93,7 @@ int board_early_init_f(void) ...@@ -93,10 +93,7 @@ int board_early_init_f(void)
mtdcr(EBC0_CFGADDR, EBC0_CFG); mtdcr(EBC0_CFGADDR, EBC0_CFG);
mtdcr(EBC0_CFGDATA, 0xf8400000); mtdcr(EBC0_CFGDATA, 0xf8400000);
/* /* Setup the GPIO pins */
* Setup the GPIO pins
* TODO: setup GPIOs via CONFIG_SYS_4xx_GPIO_TABLE in board's config file
*/
out_be32((void *)GPIO0_OR, 0x40000102); out_be32((void *)GPIO0_OR, 0x40000102);
out_be32((void *)GPIO0_TCR, 0x4c90011f); out_be32((void *)GPIO0_TCR, 0x4c90011f);
out_be32((void *)GPIO0_OSRL, 0x28051400); out_be32((void *)GPIO0_OSRL, 0x28051400);
...@@ -259,7 +256,7 @@ int misc_init_r(void) ...@@ -259,7 +256,7 @@ int misc_init_r(void)
* USB suff... * USB suff...
*/ */
if ((act == NULL || strcmp(act, "host") == 0) && 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 */ /* SDR Setting */
mfsdr(SDR0_PFC1, sdr0_pfc1); mfsdr(SDR0_PFC1, sdr0_pfc1);
mfsdr(SDR0_USB2D0CR, usb2d0cr); mfsdr(SDR0_USB2D0CR, usb2d0cr);
...@@ -326,16 +323,16 @@ int misc_init_r(void) ...@@ -326,16 +323,16 @@ int misc_init_r(void)
mtsdr(SDR0_SRST1, 0x00000000); mtsdr(SDR0_SRST1, 0x00000000);
mtsdr(SDR0_SRST0, 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 */ /* enable power on USB socket */
out_be32((void*)GPIO1_OR, out_be32((void *)GPIO1_OR,
in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); in_be32((void *)GPIO1_OR) & ~GPIO1_USB_PWR_N);
} }
printf("USB: Host\n"); printf("USB: Host\n");
} else if ((strcmp(act, "dev") == 0) || } 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); mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK; usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK;
...@@ -414,30 +411,31 @@ int misc_init_r(void) ...@@ -414,30 +411,31 @@ int misc_init_r(void)
#endif #endif
/* turn off POST LED */ /* 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 */ /* 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; return 0;
} }
int is_monarch(void) int is_monarch(void)
{ {
if (in_be32((void*)GPIO1_IR) & GPIO1_NONMONARCH) if (in_be32((void *)GPIO1_IR) & GPIO1_NONMONARCH)
return 0; return 0;
return 1; 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 1;
return 0; 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) int checkboard(void)
...@@ -495,7 +493,7 @@ void pci_target_init(struct pci_controller *hose) ...@@ -495,7 +493,7 @@ void pci_target_init(struct pci_controller *hose)
out32r(PCIL0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute */ out32r(PCIL0_PMM0MA, 0x00000000); /* PMM0 Mask/Attribute */
/* - disabled b4 setting */ /* - disabled b4 setting */
out32r(PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 Local Address */ 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_PMM0PCIHA, 0x00000000); /* PMM0 PCI High Address */
out32r(PCIL0_PMM0MA, 0xc0000001); /* 1G + No prefetching, */ out32r(PCIL0_PMM0MA, 0xc0000001); /* 1G + No prefetching, */
/* and enable region */ /* and enable region */
...@@ -532,7 +530,8 @@ void pci_target_init(struct pci_controller *hose) ...@@ -532,7 +530,8 @@ void pci_target_init(struct pci_controller *hose)
if (is_monarch()) { if (is_monarch()) {
/* BAR2: map FPGA registers behind system memory at 1GB */ /* 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) ...@@ -562,10 +561,10 @@ void pci_target_init(struct pci_controller *hose)
CONFIG_SYS_PCI_CLASSCODE_NONMONARCH); CONFIG_SYS_PCI_CLASSCODE_NONMONARCH);
/* PCI configuration done: release ERREADY */ /* PCI configuration done: release ERREADY */
out_be32((void*)GPIO1_OR, out_be32((void *)GPIO1_OR,
in_be32((void*)GPIO1_OR) | GPIO1_PPC_EREADY); in_be32((void *)GPIO1_OR) | GPIO1_PPC_EREADY);
out_be32((void*)GPIO1_TCR, out_be32((void *)GPIO1_TCR,
in_be32((void*)GPIO1_TCR) | GPIO1_PPC_EREADY); in_be32((void *)GPIO1_TCR) | GPIO1_PPC_EREADY);
} else { } else {
/* Program the board's subsystem id/classcode */ /* Program the board's subsystem id/classcode */
pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID, pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID,
...@@ -595,14 +594,14 @@ void pci_master_init(struct pci_controller *hose) ...@@ -595,14 +594,14 @@ void pci_master_init(struct pci_controller *hose)
static void wait_for_pci_ready(void) 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) ... "); printf("PCI: Waiting for EREADY (CTRL-C to skip) ... ");
while (1) { while (1) {
if (ctrlc()) { if (ctrlc()) {
puts("abort\n"); puts("abort\n");
break; break;
} }
if (in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY) { if (in_be32((void *)GPIO1_IR) & GPIO1_PPC_EREADY) {
printf("done\n"); printf("done\n");
break; break;
} }
...@@ -641,34 +640,73 @@ int is_pci_host(struct pci_controller *hose) ...@@ -641,34 +640,73 @@ int is_pci_host(struct pci_controller *hose)
#endif /* defined(CONFIG_PCI) */ #endif /* defined(CONFIG_PCI) */
#ifdef CONFIG_RESET_PHY_R #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; /* adjust LED behavior */
unsigned short val_method, val_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 */ miiphy_write(devname, phy_addr, 0x11, 0x0010);
if ((s = getenv("bd_type")) && miiphy_write(devname, phy_addr, 0x11, behavior);
((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) { miiphy_write(devname, phy_addr, 0x10, method);
val_method = 0x0e0a; miiphy_write(devname, phy_addr, 0x1f, 0x0000);
val_behavior = 0x0cf2;
} else { return 0;
/* PMC440 standard type */ }
val_method = 0x0e10;
val_behavior = 0x0cf0; 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) { if ((id1 != 0x0022) || ((id2 & 0xfff0) != 0x1620)) {
miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010); printf("Phy%d: unexpected id\n", phy_addr);
miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior); return -1;
miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method);
miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000);
} }
if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) { /* MMD 2.08: adjust tx_clk pad skew */
miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010); miiphy_write(devname, phy_addr, 0x0d, 2);
miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior); miiphy_write(devname, phy_addr, 0x0e, 8);
miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method); miiphy_write(devname, phy_addr, 0x0d, 0x4002);
miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000); 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 #endif
...@@ -729,7 +767,6 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, ...@@ -729,7 +767,6 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset,
* We must write the address again when changing pages * We must write the address again when changing pages
* because the address counter only increments within a page. * because the address counter only increments within a page.
*/ */
while (offset < end) { while (offset < end) {
unsigned alen, len; unsigned alen, len;
unsigned maxlen; unsigned maxlen;
...@@ -771,8 +808,8 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, ...@@ -771,8 +808,8 @@ int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset,
return rcode; return rcode;
} }
int bootstrap_eeprom_read (unsigned dev_addr, unsigned offset, static int bootstrap_eeprom_read(unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt) uchar *buffer, unsigned cnt)
{ {
unsigned end = offset + cnt; unsigned end = offset + cnt;
unsigned blk_off; unsigned blk_off;
...@@ -820,10 +857,10 @@ int board_usb_init(int index, enum usb_init_type init) ...@@ -820,10 +857,10 @@ int board_usb_init(int index, enum usb_init_type init)
int i; int i;
if ((act == NULL || strcmp(act, "host") == 0) && 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 */ /* enable power on USB socket */
out_be32((void*)GPIO1_OR, out_be32((void *)GPIO1_OR,
in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N); in_be32((void *)GPIO1_OR) & ~GPIO1_USB_PWR_N);
for (i=0; i<1000; i++) for (i=0; i<1000; i++)
udelay(1000); udelay(1000);
...@@ -834,7 +871,7 @@ int board_usb_init(int index, enum usb_init_type init) ...@@ -834,7 +871,7 @@ int board_usb_init(int index, enum usb_init_type init)
int usb_board_stop(void) int usb_board_stop(void)
{ {
/* disable power on USB socket */ /* 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; return 0;
} }
...@@ -858,8 +895,8 @@ void ft_board_setup(void *blob, bd_t *bd) ...@@ -858,8 +895,8 @@ void ft_board_setup(void *blob, bd_t *bd)
rc = fdt_find_and_setprop(blob, "/plb/pci@1ec000000", "status", rc = fdt_find_and_setprop(blob, "/plb/pci@1ec000000", "status",
"disabled", sizeof("disabled"), 1); "disabled", sizeof("disabled"), 1);
if (rc) { if (rc) {
printf("Unable to update property status in PCI node, err=%s\n", printf("Unable to update property status in PCI node, ");
fdt_strerror(rc)); printf("err=%s\n", fdt_strerror(rc));
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册