diff options
Diffstat (limited to 'board/gdsys')
| -rw-r--r-- | board/gdsys/405ex/405ex.c | 250 | ||||
| -rw-r--r-- | board/gdsys/405ex/405ex.h | 10 | ||||
| -rw-r--r-- | board/gdsys/405ex/Makefile | 53 | ||||
| -rw-r--r-- | board/gdsys/405ex/chip_config.c | 96 | ||||
| -rw-r--r-- | board/gdsys/405ex/io64.c | 384 | ||||
| -rw-r--r-- | board/gdsys/common/Makefile | 1 | ||||
| -rw-r--r-- | board/gdsys/common/miiphybb.c | 58 | 
7 files changed, 844 insertions, 8 deletions
| diff --git a/board/gdsys/405ex/405ex.c b/board/gdsys/405ex/405ex.c new file mode 100644 index 000000000..0d25214f4 --- /dev/null +++ b/board/gdsys/405ex/405ex.c @@ -0,0 +1,250 @@ +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/ppc405.h> +#include <asm/processor.h> +#include <asm/io.h> + +#include <gdsys_fpga.h> + +#include "405ex.h" + +#define REFLECTION_TESTPATTERN 0xdede +#define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff) + +DECLARE_GLOBAL_DATA_PTR; + +int get_fpga_state(unsigned dev) +{ +	return gd->fpga_state[dev]; +} + +void print_fpga_state(unsigned dev) +{ +	if (gd->fpga_state[dev] & FPGA_STATE_DONE_FAILED) +		puts("       Waiting for FPGA-DONE timed out.\n"); +	if (gd->fpga_state[dev] & FPGA_STATE_REFLECTION_FAILED) +		puts("       FPGA reflection test failed.\n"); +} + +int board_early_init_f(void) +{ +	u32 val; + +	/*--------------------------------------------------------------------+ +	 | Interrupt controller setup +	 +--------------------------------------------------------------------+ +	+---------------------------------------------------------------------+ +	|Interrupt| Source                            | Pol.  | Sensi.| Crit. | +	+---------+-----------------------------------+-------+-------+-------+ +	| IRQ 00  | UART0                             | High  | Level | Non   | +	| IRQ 01  | UART1                             | High  | Level | Non   | +	| IRQ 02  | IIC0                              | High  | Level | Non   | +	| IRQ 03  | TBD                               | High  | Level | Non   | +	| IRQ 04  | TBD                               | High  | Level | Non   | +	| IRQ 05  | EBM                               | High  | Level | Non   | +	| IRQ 06  | BGI                               | High  | Level | Non   | +	| IRQ 07  | IIC1                              | Rising| Edge  | Non   | +	| IRQ 08  | SPI                               | High  | Lvl/ed| Non   | +	| IRQ 09  | External IRQ 0 - (PCI-Express)    | pgm H | Pgm   | Non   | +	| IRQ 10  | MAL TX EOB                        | High  | Level | Non   | +	| IRQ 11  | MAL RX EOB                        | High  | Level | Non   | +	| IRQ 12  | DMA Channel 0 FIFO Full           | High  | Level | Non   | +	| IRQ 13  | DMA Channel 0 Stat FIFO           | High  | Level | Non   | +	| IRQ 14  | DMA Channel 1 FIFO Full           | High  | Level | Non   | +	| IRQ 15  | DMA Channel 1 Stat FIFO           | High  | Level | Non   | +	| IRQ 16  | PCIE0 AL                          | high  | Level | Non   | +	| IRQ 17  | PCIE0 VPD access                  | rising| Edge  | Non   | +	| IRQ 18  | PCIE0 hot reset request           | rising| Edge  | Non   | +	| IRQ 19  | PCIE0 hot reset request           | faling| Edge  | Non   | +	| IRQ 20  | PCIE0 TCR                         | High  | Level | Non   | +	| IRQ 21  | PCIE0 MSI level0                  | High  | Level | Non   | +	| IRQ 22  | PCIE0 MSI level1                  | High  | Level | Non   | +	| IRQ 23  | Security EIP-94                   | High  | Level | Non   | +	| IRQ 24  | EMAC0 interrupt                   | High  | Level | Non   | +	| IRQ 25  | EMAC1 interrupt                   | High  | Level | Non   | +	| IRQ 26  | PCIE0 MSI level2                  | High  | Level | Non   | +	| IRQ 27  | External IRQ 4                    | pgm H | Pgm   | Non   | +	| IRQ 28  | UIC2 Non-critical Int.            | High  | Level | Non   | +	| IRQ 29  | UIC2 Critical Interrupt           | High  | Level | Crit. | +	| IRQ 30  | UIC1 Non-critical Int.            | High  | Level | Non   | +	| IRQ 31  | UIC1 Critical Interrupt           | High  | Level | Crit. | +	|---------------------------------------------------------------------- +	| IRQ 32  | MAL Serr                          | High  | Level | Non   | +	| IRQ 33  | MAL Txde                          | High  | Level | Non   | +	| IRQ 34  | MAL Rxde                          | High  | Level | Non   | +	| IRQ 35  | PCIE0 bus master VC0              |falling| Edge  | Non   | +	| IRQ 36  | PCIE0 DCR Error                   | High  | Level | Non   | +	| IRQ 37  | EBC                               | High  |Lvl Edg| Non   | +	| IRQ 38  | NDFC                              | High  | Level | Non   | +	| IRQ 39  | GPT Compare Timer 8               | Risin | Edge  | Non   | +	| IRQ 40  | GPT Compare Timer 9               | Risin | Edge  | Non   | +	| IRQ 41  | PCIE1 AL                          | high  | Level | Non   | +	| IRQ 42  | PCIE1 VPD access                  | rising| edge  | Non   | +	| IRQ 43  | PCIE1 hot reset request           | rising| Edge  | Non   | +	| IRQ 44  | PCIE1 hot reset request           | faling| Edge  | Non   | +	| IRQ 45  | PCIE1 TCR                         | High  | Level | Non   | +	| IRQ 46  | PCIE1 bus master VC0              |falling| Edge  | Non   | +	| IRQ 47  | GPT Compare Timer 3               | Risin | Edge  | Non   | +	| IRQ 48  | GPT Compare Timer 4               | Risin | Edge  | Non   | +	| IRQ 49  | Ext. IRQ 7                        |pgm/Fal|pgm/Lvl| Non   | +	| IRQ 50  | Ext. IRQ 8 -                      |pgm (H)|pgm/Lvl| Non   | +	| IRQ 51  | Ext. IRQ 9                        |pgm (H)|pgm/Lvl| Non   | +	| IRQ 52  | GPT Compare Timer 5               | high  | Edge  | Non   | +	| IRQ 53  | GPT Compare Timer 6               | high  | Edge  | Non   | +	| IRQ 54  | GPT Compare Timer 7               | high  | Edge  | Non   | +	| IRQ 55  | Serial ROM                        | High  | Level | Non   | +	| IRQ 56  | GPT Decrement Pulse               | High  | Level | Non   | +	| IRQ 57  | Ext. IRQ 2                        |pgm/Fal|pgm/Lvl| Non   | +	| IRQ 58  | Ext. IRQ 5                        |pgm/Fal|pgm/Lvl| Non   | +	| IRQ 59  | Ext. IRQ 6                        |pgm/Fal|pgm/Lvl| Non   | +	| IRQ 60  | EMAC0 Wake-up                     | High  | Level | Non   | +	| IRQ 61  | Ext. IRQ 1                        |pgm/Fal|pgm/Lvl| Non   | +	| IRQ 62  | EMAC1 Wake-up                     | High  | Level | Non   | +	|---------------------------------------------------------------------- +	| IRQ 64  | PE0 AL                            | High  | Level | Non   | +	| IRQ 65  | PE0 VPD Access                    | Risin | Edge  | Non   | +	| IRQ 66  | PE0 Hot Reset Request             | Risin | Edge  | Non   | +	| IRQ 67  | PE0 Hot Reset Request             | Falli | Edge  | Non   | +	| IRQ 68  | PE0 TCR                           | High  | Level | Non   | +	| IRQ 69  | PE0 BusMaster VCO                 | Falli | Edge  | Non   | +	| IRQ 70  | PE0 DCR Error                     | High  | Level | Non   | +	| IRQ 71  | Reserved                          | N/A   | N/A   | Non   | +	| IRQ 72  | PE1 AL                            | High  | Level | Non   | +	| IRQ 73  | PE1 VPD Access                    | Risin | Edge  | Non   | +	| IRQ 74  | PE1 Hot Reset Request             | Risin | Edge  | Non   | +	| IRQ 75  | PE1 Hot Reset Request             | Falli | Edge  | Non   | +	| IRQ 76  | PE1 TCR                           | High  | Level | Non   | +	| IRQ 77  | PE1 BusMaster VCO                 | Falli | Edge  | Non   | +	| IRQ 78  | PE1 DCR Error                     | High  | Level | Non   | +	| IRQ 79  | Reserved                          | N/A   | N/A   | Non   | +	| IRQ 80  | PE2 AL                            | High  | Level | Non   | +	| IRQ 81  | PE2 VPD Access                    | Risin | Edge  | Non   | +	| IRQ 82  | PE2 Hot Reset Request             | Risin | Edge  | Non   | +	| IRQ 83  | PE2 Hot Reset Request             | Falli | Edge  | Non   | +	| IRQ 84  | PE2 TCR                           | High  | Level | Non   | +	| IRQ 85  | PE2 BusMaster VCO                 | Falli | Edge  | Non   | +	| IRQ 86  | PE2 DCR Error                     | High  | Level | Non   | +	| IRQ 87  | Reserved                          | N/A   | N/A   | Non   | +	| IRQ 88  | External IRQ(5)                   | Progr | Progr | Non   | +	| IRQ 89  | External IRQ 4 - Ethernet         | Progr | Progr | Non   | +	| IRQ 90  | External IRQ 3 - PCI-X            | Progr | Progr | Non   | +	| IRQ 91  | External IRQ 2 - PCI-X            | Progr | Progr | Non   | +	| IRQ 92  | External IRQ 1 - PCI-X            | Progr | Progr | Non   | +	| IRQ 93  | External IRQ 0 - PCI-X            | Progr | Progr | Non   | +	| IRQ 94  | Reserved                          | N/A   | N/A   | Non   | +	| IRQ 95  | Reserved                          | N/A   | N/A   | Non   | +	|--------------------------------------------------------------------- +	+---------+-----------------------------------+-------+-------+------*/ +	/*--------------------------------------------------------------------+ +	 | Initialise UIC registers.  Clear all interrupts.  Disable all +	 | interrupts. +	 | Set critical interrupt values.  Set interrupt polarities.  Set +	 | interrupt trigger levels.  Make bit 0 High  priority.  Clear all +	 | interrupts again. +	 +-------------------------------------------------------------------*/ + +	mtdcr(UIC2SR, 0xffffffff); /* Clear all interrupts */ +	mtdcr(UIC2ER, 0x00000000); /* disable all interrupts */ +	mtdcr(UIC2CR, 0x00000000); /* Set Critical / Non Critical interrupts */ +	mtdcr(UIC2PR, 0xf7ffffff); /* Set Interrupt Polarities */ +	mtdcr(UIC2TR, 0x01e1fff8); /* Set Interrupt Trigger Levels */ +	mtdcr(UIC2VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ +	mtdcr(UIC2SR, 0x00000000); /* clear all interrupts */ +	mtdcr(UIC2SR, 0xffffffff); /* clear all interrupts */ + +	mtdcr(UIC1SR, 0xffffffff); /* Clear all interrupts */ +	mtdcr(UIC1ER, 0x00000000); /* disable all interrupts */ +	mtdcr(UIC1CR, 0x00000000); /* Set Critical / Non Critical interrupts */ +	mtdcr(UIC1PR, 0xfffac785); /* Set Interrupt Polarities */ +	mtdcr(UIC1TR, 0x001d0040); /* Set Interrupt Trigger Levels */ +	mtdcr(UIC1VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ +	mtdcr(UIC1SR, 0x00000000); /* clear all interrupts */ +	mtdcr(UIC1SR, 0xffffffff); /* clear all interrupts */ + +	mtdcr(UIC0SR, 0xffffffff); /* Clear all interrupts */ +	mtdcr(UIC0ER, 0x0000000a); /* Disable all interrupts */ +				   /* Except cascade UIC0 and UIC1 */ +	mtdcr(UIC0CR, 0x00000000); /* Set Critical / Non Critical interrupts */ +	mtdcr(UIC0PR, 0xffbfefef); /* Set Interrupt Polarities */ +	mtdcr(UIC0TR, 0x00007000); /* Set Interrupt Trigger Levels */ +	mtdcr(UIC0VR, 0x00000001); /* Set Vect base=0,INT31 Highest priority */ +	mtdcr(UIC0SR, 0x00000000); /* clear all interrupts */ +	mtdcr(UIC0SR, 0xffffffff); /* clear all interrupts */ + +	/* +	 * Note: Some cores are still in reset when the chip starts, so +	 * take them out of reset +	 */ +	mtsdr(SDR0_SRST, 0); + +	/* +	 * Configure PFC (Pin Function Control) registers +	 */ +	val = SDR0_PFC1_GPT_FREQ; +	mtsdr(SDR0_PFC1, val); + +	return 0; +} + +int board_early_init_r(void) +{ +	unsigned k; +	unsigned ctr; + +	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) +		gd->fpga_state[k] = 0; + +	/* +	 * reset FPGA +	 */ +	gd405ex_init(); + +	gd405ex_set_fpga_reset(1); + +	gd405ex_setup_hw(); + +	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) { +		ctr = 0; +		while (!gd405ex_get_fpga_done(k)) { +			udelay(100000); +			if (ctr++ > 5) { +				gd->fpga_state[k] |= FPGA_STATE_DONE_FAILED; +				break; +			} +		} +	} + +	udelay(10); + +	gd405ex_set_fpga_reset(0); + +	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) { +		ihs_fpga_t *fpga = (ihs_fpga_t *) CONFIG_SYS_FPGA_BASE(k); +#ifdef CONFIG_SYS_FPGA_NO_RFL_HI +		u16 *reflection_target = &fpga->reflection_low; +#else +		u16 *reflection_target = &fpga->reflection_high; +#endif +		/* +		 * wait for fpga out of reset +		 */ +		ctr = 0; +		while (1) { +			out_le16(&fpga->reflection_low, +				REFLECTION_TESTPATTERN); + +			if (in_le16(reflection_target) == +				REFLECTION_TESTPATTERN_INV) +				break; + +			udelay(100000); +			if (ctr++ > 5) { +				gd->fpga_state[k] |= +					FPGA_STATE_REFLECTION_FAILED; +				break; +			} +		} +	} + +	return 0; +} diff --git a/board/gdsys/405ex/405ex.h b/board/gdsys/405ex/405ex.h new file mode 100644 index 000000000..b15623f3f --- /dev/null +++ b/board/gdsys/405ex/405ex.h @@ -0,0 +1,10 @@ +#ifndef __405EX_H_ +#define __405EX_H_ + +/* functions to be provided by board implementation */ +void gd405ex_init(void); +void gd405ex_set_fpga_reset(unsigned state); +void gd405ex_setup_hw(void); +int gd405ex_get_fpga_done(unsigned fpga); + +#endif /* __405EX_H_ */ diff --git a/board/gdsys/405ex/Makefile b/board/gdsys/405ex/Makefile new file mode 100644 index 000000000..4549705e5 --- /dev/null +++ b/board/gdsys/405ex/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2007 +# Stefan Roese, DENX Software Engineering, sr@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)lib$(BOARD).o + +COBJS-$(CONFIG_IO64) += io64.o + +COBJS-$(CONFIG_CMD_CHIP_CONFIG) += chip_config.o + +COBJS   := $(BOARD).o $(COBJS-y) + +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB):	$(obj).depend $(OBJS) +	$(call cmd_link_o_target, $(OBJS)) + +clean: +	rm -f $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/gdsys/405ex/chip_config.c b/board/gdsys/405ex/chip_config.c new file mode 100644 index 000000000..12cb3bf16 --- /dev/null +++ b/board/gdsys/405ex/chip_config.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2009 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <common.h> +#include <asm/ppc4xx_config.h> + +/* NAND booting versions differ in bytes: 6, 8, 9, 11, 12 */ + +struct ppc4xx_config ppc4xx_config_val[] = { +	{ +		"333-nor", "NOR  CPU: 333 PLB: 166 OPB:  83 EBC:  83", +		{ +			0x8c, 0x12, 0xec, 0x12, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"400-133-nor", "NOR  CPU: 400 PLB: 133 OPB:  66 EBC:  66", +		{ +			0x8e, 0x0e, 0xe8, 0x13, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"400-200-66-nor", "NOR  CPU: 400 PLB: 200 OPB:  66 EBC:  66", +		{ +			0x8e, 0x0e, 0xe8, 0x12, 0xd8, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"400-nor", "NOR  CPU: 400 PLB: 200 OPB: 100 EBC: 100", +		{ +			0x8e, 0x0e, 0xe8, 0x12, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"533-nor", "NOR  CPU: 533 PLB: 177 OPB:  88 EBC:  88", +		{ +			0x8e, 0x43, 0x60, 0x13, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"533-nand", "NOR  CPU: 533 PLB: 177 OPB:  88 EBC:  88", +		{ +			0x8e, 0x43, 0x60, 0x13, 0x98, 0x00, 0x0f, 0x00, +			0xa0, 0x68, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"600-nor", "NOR  CPU: 600 PLB: 200 OPB: 100 EBC: 100", +		{ +			0x8d, 0x02, 0x34, 0x13, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"600-nand", "NOR  CPU: 600 PLB: 200 OPB: 100 EBC: 100", +		{ +			0x8d, 0x02, 0x34, 0x13, 0x98, 0x00, 0x0f, 0x00, +			0xa0, 0x68, 0x23, 0x58, 0x0d, 0x05, 0x00, 0x00 +		} +	}, +	{ +		"666-nor", "NOR  CPU: 666 PLB: 222 OPB: 111 EBC: 111", +		{ +			0x8d, 0x03, 0x78, 0x13, 0x98, 0x00, 0x0a, 0x00, +			0x40, 0x08, 0x23, 0x50, 0x00, 0x05, 0x00, 0x00 +		} +	}, +}; + +int ppc4xx_config_count = ARRAY_SIZE(ppc4xx_config_val); diff --git a/board/gdsys/405ex/io64.c b/board/gdsys/405ex/io64.c new file mode 100644 index 000000000..a997571f0 --- /dev/null +++ b/board/gdsys/405ex/io64.c @@ -0,0 +1,384 @@ +/* + * (C) Copyright 2010 + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de + * + * based on kilauea.c + * by Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/ppc405.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/ppc4xx-gpio.h> +#include <flash.h> + +#include <pca9698.h> + +#include "405ex.h" +#include <gdsys_fpga.h> + +#include <miiphy.h> +#include <i2c.h> +#include <dtt.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define PHYREG_CONTROL				0 +#define PHYREG_PAGE_ADDRESS			22 +#define PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1	16 +#define PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2	26 +#define PHYREG_PG2_MAC_SPECIFIC_STATUS_1	17 +#define PHYREG_PG2_MAC_SPECIFIC_CONTROL		21 + +#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE) +#define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100) +#define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200) +#define LATCH3_BASE (CONFIG_SYS_LATCH_BASE + 0x300) + +enum { +	UNITTYPE_CCD_SWITCH = 1, +}; + +enum { +	HWVER_100 = 0, +	HWVER_110 = 1, +}; + +static inline void blank_string(int size) +{ +	int i; + +	for (i = 0; i < size; i++) +		putc('\b'); +	for (i = 0; i < size; i++) +		putc(' '); +	for (i = 0; i < size; i++) +		putc('\b'); +} + +/* + * Board early initialization function + */ +int misc_init_r(void) +{ +	/* startup fans */ +	dtt_init(); + +#ifdef CONFIG_ENV_IS_IN_FLASH +	/* Monitor protection ON by default */ +	flash_protect(FLAG_PROTECT_SET, +		      -CONFIG_SYS_MONITOR_LEN, +		      0xffffffff, +		      &flash_info[0]); +#endif + +	return 0; +} + +static void print_fpga_info(unsigned dev) +{ +	ihs_fpga_t *fpga = (ihs_fpga_t *) CONFIG_SYS_FPGA_BASE(dev); +	u16 versions = in_le16(&fpga->versions); +	u16 fpga_version = in_le16(&fpga->fpga_version); +	u16 fpga_features = in_le16(&fpga->fpga_features); +	int fpga_state = get_fpga_state(dev); + +	unsigned unit_type; +	unsigned hardware_version; +	unsigned feature_channels; +	unsigned feature_expansion; + +	printf("FPGA%d: ", dev); +	if (fpga_state & FPGA_STATE_PLATFORM) +		printf("(legacy) "); + +	if (fpga_state & FPGA_STATE_DONE_FAILED) { +		printf(" done timed out\n"); +		return; +	} + +	if (fpga_state & FPGA_STATE_REFLECTION_FAILED) { +		printf(" refelectione test failed\n"); +		return; +	} + +	unit_type = (versions & 0xf000) >> 12; +	hardware_version = versions & 0x000f; +	feature_channels = fpga_features & 0x007f; +	feature_expansion = fpga_features & (1<<15); + +	switch (unit_type) { +	case UNITTYPE_CCD_SWITCH: +		printf("CCD-Switch"); +		break; + +	default: +		printf("UnitType %d(not supported)", unit_type); +		break; +	} + +	switch (hardware_version) { +	case HWVER_100: +		printf(" HW-Ver 1.00\n"); +		break; + +	case HWVER_110: +		printf(" HW-Ver 1.10\n"); +		break; + +	default: +		printf(" HW-Ver %d(not supported)\n", +		       hardware_version); +		break; +	} + +	printf("       FPGA V %d.%02d, features:", +		fpga_version / 100, fpga_version % 100); + +	printf(" %d channel(s)", feature_channels); + +	printf(", expansion %ssupported\n", feature_expansion ? "" : "un"); +} + +int checkboard(void) +{ +	char *s = getenv("serial#"); + +	printf("Board: CATCenter Io64\n"); + +	if (s != NULL) { +		puts(", serial# "); +		puts(s); +	} + +	return 0; +} + +int configure_gbit_phy(char *bus, unsigned char addr) +{ +	unsigned short value; + +	/* select page 0 */ +	if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000)) +		goto err_out; +	/* switch to powerdown */ +	if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, +		&value)) +		goto err_out; +	if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, +		value | 0x0004)) +		goto err_out; +	/* select page 2 */ +	if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002)) +		goto err_out; +	/* disable SGMII autonegotiation */ +	if (miiphy_write(bus, addr, PHYREG_PG2_MAC_SPECIFIC_CONTROL, 48)) +		goto err_out; +	/* select page 0 */ +	if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000)) +		goto err_out; +	/* switch from powerdown to normal operation */ +	if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, +		&value)) +		goto err_out; +	if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, +		value & ~0x0004)) +		goto err_out; +	/* reset phy so settings take effect */ +	if (miiphy_write(bus, addr, PHYREG_CONTROL, 0x9140)) +		goto err_out; + +	return 0; + +err_out: +	printf("Error writing to the PHY addr=%02x\n", addr); +	return -1; +} + +int verify_gbit_phy(char *bus, unsigned char addr) +{ +	unsigned short value; + +	/* select page 2 */ +	if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002)) +		goto err_out; +	/* verify SGMII link status */ +	if (miiphy_read(bus, addr, PHYREG_PG2_MAC_SPECIFIC_STATUS_1, &value)) +		goto err_out; +	if (!(value & (1 << 10))) +		return -2; + +	return 0; + +err_out: +	printf("Error writing to the PHY addr=%02x\n", addr); +	return -1; +} + +int last_stage_init(void) +{ +	unsigned int k; +	unsigned int fpga; +	ihs_fpga_t *fpga0 = (ihs_fpga_t *) CONFIG_SYS_FPGA_BASE(0); +	ihs_fpga_t *fpga1 = (ihs_fpga_t *) CONFIG_SYS_FPGA_BASE(1); +	int failed = 0; +	char str_phys[] = "Setup PHYs -"; +	char str_serdes[] = "Start SERDES blocks"; +	char str_channels[] = "Start FPGA channels"; +	char str_locks[] = "Verify SERDES locks"; +	char str_status[] = "Verify PHY status -"; +	char slash[] = "\\|/-\\|/-"; + +	print_fpga_info(0); +	print_fpga_info(1); + +	/* setup Gbit PHYs */ +	puts("TRANS: "); +	puts(str_phys); +	miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME, +		bb_miiphy_read, bb_miiphy_write); + +	for (k = 0; k < 32; ++k) { +		configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k); +		putc('\b'); +		putc(slash[k % 8]); +	} + +	miiphy_register(CONFIG_SYS_GBIT_MII1_BUSNAME, +		bb_miiphy_read, bb_miiphy_write); + +	for (k = 0; k < 32; ++k) { +		configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k); +		putc('\b'); +		putc(slash[k % 8]); +	} +	blank_string(strlen(str_phys)); + +	/* take fpga serdes blocks out of reset */ +	puts(str_serdes); +	udelay(500000); +	out_le16(&fpga0->quad_serdes_reset, 0); +	out_le16(&fpga1->quad_serdes_reset, 0); +	blank_string(strlen(str_serdes)); + +	/* take channels out of reset */ +	puts(str_channels); +	udelay(500000); +	for (fpga = 0; fpga < 2; ++fpga) { +		u16 *ch0_config_int = &(fpga ? fpga1 : fpga0)->ch0_config_int; +		for (k = 0; k < 32; ++k) +			out_le16(ch0_config_int + 4 * k, 0); +	} +	blank_string(strlen(str_channels)); + +	/* verify channels serdes lock */ +	puts(str_locks); +	udelay(500000); +	for (fpga = 0; fpga < 2; ++fpga) { +		u16 *ch0_status_int = &(fpga ? fpga1 : fpga0)->ch0_status_int; +		for (k = 0; k < 32; ++k) { +			u16 status = in_le16(ch0_status_int + 4*k); +			if (!(status & (1 << 4))) { +				failed = 1; +				printf("fpga %d channel %d: no serdes lock\n", +					fpga, k); +			} +			/* reset events */ +			out_le16(ch0_status_int + 4*k, status); +		} +	} +	blank_string(strlen(str_locks)); + +	/* verify phy status */ +	puts(str_status); +	for (k = 0; k < 32; ++k) { +		if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) { +			printf("verify baseboard phy %d failed\n", k); +			failed = 1; +		} +		putc('\b'); +		putc(slash[k % 8]); +	} +	for (k = 0; k < 32; ++k) { +		if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) { +			printf("verify extensionboard phy %d failed\n", k); +			failed = 1; +		} +		putc('\b'); +		putc(slash[k % 8]); +	} +	blank_string(strlen(str_status)); + +	printf("Starting 64 channels %s\n", failed ? "failed" : "ok"); + +	return 0; +} + +void gd405ex_init(void) +{ +	unsigned int k; + +	if (i2c_probe(0x22)) { /* i2c_probe returns 0 on success */ +		for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) +			gd->fpga_state[k] |= FPGA_STATE_PLATFORM; +	} else { +		pca9698_direction_output(0x22, 39, 1); +	} +} + +void gd405ex_set_fpga_reset(unsigned state) +{ +	int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + +	if (legacy) { +		if (state) { +			out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET); +			out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET); +		} else { +			out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT); +			out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT); +		} +	} else { +		pca9698_set_value(0x22, 39, state ? 0 : 1); +	} +} + +void gd405ex_setup_hw(void) +{ +	gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED_N, 0); +	gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED, 1); +} + +int gd405ex_get_fpga_done(unsigned fpga) +{ +	int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; + +	if (legacy) +		return in_le16((void *)LATCH3_BASE) +			& CONFIG_SYS_FPGA_DONE(fpga); +	else +		return pca9698_get_value(0x22, fpga ? 9 : 8); +} diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile index 2868cc8bd..05dd65df7 100644 --- a/board/gdsys/common/Makefile +++ b/board/gdsys/common/Makefile @@ -30,6 +30,7 @@ endif  LIB	= $(obj)lib$(VENDOR).o  COBJS-$(CONFIG_IO) += miiphybb.o +COBJS-$(CONFIG_IO64) += miiphybb.o  COBJS-$(CONFIG_IOCON) += osd.o  COBJS-$(CONFIG_DLVISION_10G) += osd.o diff --git a/board/gdsys/common/miiphybb.c b/board/gdsys/common/miiphybb.c index e56e96650..46f1a1ecb 100644 --- a/board/gdsys/common/miiphybb.c +++ b/board/gdsys/common/miiphybb.c @@ -26,6 +26,11 @@  #include <asm/io.h> +struct io_bb_pinset { +	int mdio; +	int mdc; +}; +  static int io_bb_mii_init(struct bb_miiphy_bus *bus)  {  	return 0; @@ -33,47 +38,57 @@ static int io_bb_mii_init(struct bb_miiphy_bus *bus)  static int io_bb_mdio_active(struct bb_miiphy_bus *bus)  { +	struct io_bb_pinset *pins = bus->priv; +  	out_be32((void *)GPIO0_TCR, -		in_be32((void *)GPIO0_TCR) | CONFIG_SYS_MDIO_PIN); +		in_be32((void *)GPIO0_TCR) | pins->mdio);  	return 0;  }  static int io_bb_mdio_tristate(struct bb_miiphy_bus *bus)  { +	struct io_bb_pinset *pins = bus->priv; +  	out_be32((void *)GPIO0_TCR, -		in_be32((void *)GPIO0_TCR) & ~CONFIG_SYS_MDIO_PIN); +		in_be32((void *)GPIO0_TCR) & ~pins->mdio);  	return 0;  }  static int io_bb_set_mdio(struct bb_miiphy_bus *bus, int v)  { +	struct io_bb_pinset *pins = bus->priv; +  	if (v)  		out_be32((void *)GPIO0_OR, -			in_be32((void *)GPIO0_OR) | CONFIG_SYS_MDIO_PIN); +			in_be32((void *)GPIO0_OR) | pins->mdio);  	else  		out_be32((void *)GPIO0_OR, -			in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_MDIO_PIN); +			in_be32((void *)GPIO0_OR) & ~pins->mdio);  	return 0;  }  static int io_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)  { -	*v = ((in_be32((void *)GPIO0_IR) & CONFIG_SYS_MDIO_PIN) != 0); +	struct io_bb_pinset *pins = bus->priv; + +	*v = ((in_be32((void *)GPIO0_IR) & pins->mdio) != 0);  	return 0;  }  static int io_bb_set_mdc(struct bb_miiphy_bus *bus, int v)  { +	struct io_bb_pinset *pins = bus->priv; +  	if (v)  		out_be32((void *)GPIO0_OR, -			in_be32((void *)GPIO0_OR) | CONFIG_SYS_MDC_PIN); +			in_be32((void *)GPIO0_OR) | pins->mdc);  	else  		out_be32((void *)GPIO0_OR, -			in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_MDC_PIN); +			in_be32((void *)GPIO0_OR) & ~pins->mdc);  	return 0;  } @@ -85,6 +100,19 @@ static int io_bb_delay(struct bb_miiphy_bus *bus)  	return 0;  } +struct io_bb_pinset io_bb_pinsets[] = { +	{ +		.mdio = CONFIG_SYS_MDIO_PIN, +		.mdc = CONFIG_SYS_MDC_PIN, +	}, +#ifdef CONFIG_SYS_GBIT_MII1_BUSNAME +	{ +		.mdio = CONFIG_SYS_MDIO1_PIN, +		.mdc = CONFIG_SYS_MDC1_PIN, +	}, +#endif +}; +  struct bb_miiphy_bus bb_miiphy_buses[] = {  	{  		.name = CONFIG_SYS_GBIT_MII_BUSNAME, @@ -95,7 +123,21 @@ struct bb_miiphy_bus bb_miiphy_buses[] = {  		.get_mdio = io_bb_get_mdio,  		.set_mdc = io_bb_set_mdc,  		.delay = io_bb_delay, -	} +		.priv = &io_bb_pinsets[0], +	}, +#ifdef CONFIG_SYS_GBIT_MII1_BUSNAME +	{ +		.name = CONFIG_SYS_GBIT_MII1_BUSNAME, +		.init = io_bb_mii_init, +		.mdio_active = io_bb_mdio_active, +		.mdio_tristate = io_bb_mdio_tristate, +		.set_mdio = io_bb_set_mdio, +		.get_mdio = io_bb_get_mdio, +		.set_mdc = io_bb_set_mdc, +		.delay = io_bb_delay, +		.priv = &io_bb_pinsets[1], +	}, +#endif  };  int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / |