diff options
| -rw-r--r-- | board/keymile/common/common.h | 5 | ||||
| -rw-r--r-- | board/keymile/km_arm/Makefile | 4 | ||||
| -rw-r--r-- | board/keymile/km_arm/fpga_config.c | 212 | ||||
| -rw-r--r-- | board/keymile/km_arm/km_arm.c | 21 | ||||
| -rw-r--r-- | boards.cfg | 2 | ||||
| -rw-r--r-- | include/configs/km/km_arm.h | 3 | ||||
| -rw-r--r-- | include/configs/km_kirkwood.h | 8 | 
7 files changed, 245 insertions, 10 deletions
| diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index f457aa30c..aab706e6c 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -131,6 +131,11 @@ struct bfticu_iomap {  int ethernet_present(void);  int ivm_read_eeprom(void); +int trigger_fpga_config(void); +int wait_for_fpga_config(void); +int fpga_reset(void); +int toggle_eeprom_spi_bus(void); +  int set_km_env(void);  int fdt_set_node_and_value(void *blob,  			char *nodename, diff --git a/board/keymile/km_arm/Makefile b/board/keymile/km_arm/Makefile index aa5125526..13d485aed 100644 --- a/board/keymile/km_arm/Makefile +++ b/board/keymile/km_arm/Makefile @@ -31,6 +31,10 @@ LIB	= $(obj)lib$(BOARD).o  COBJS	:= $(BOARD).o ../common/common.o ../common/ivm.o +ifdef CONFIG_KM_FPGA_CONFIG +COBJS	+= fpga_config.o +endif +  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS))  SOBJS	:= $(addprefix $(obj),$(SOBJS)) diff --git a/board/keymile/km_arm/fpga_config.c b/board/keymile/km_arm/fpga_config.c new file mode 100644 index 000000000..4356b9a64 --- /dev/null +++ b/board/keymile/km_arm/fpga_config.c @@ -0,0 +1,212 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <i2c.h> +#include <asm/errno.h> + +/* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */ +#define KM_XLX_PROGRAM_B_PIN    39 + +#define BOCO_ADDR	0x10 + +#define ID_REG		0x00 +#define BOCO2_ID	0x5b + +static int check_boco2(void) +{ +	int ret; +	u8 id; + +	ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1); +	if (ret) { +		printf("%s: error reading the BOCO id !!\n", __func__); +		return ret; +	} + +	return (id == BOCO2_ID); +} + +static int boco_clear_bits(u8 reg, u8 flags) +{ +	int ret; +	u8 regval; + +	/* give access to the EEPROM from FPGA */ +	ret = i2c_read(BOCO_ADDR, reg, 1, ®val, 1); +	if (ret) { +		printf("%s: error reading the BOCO @%#x !!\n", +			__func__, reg); +		return ret; +	} +	regval &= ~flags; +	ret = i2c_write(BOCO_ADDR, reg, 1, ®val, 1); +	if (ret) { +		printf("%s: error writing the BOCO @%#x !!\n", +			__func__, reg); +		return ret; +	} + +	return 0; +} + +static int boco_set_bits(u8 reg, u8 flags) +{ +	int ret; +	u8 regval; + +	/* give access to the EEPROM from FPGA */ +	ret = i2c_read(BOCO_ADDR, reg, 1, ®val, 1); +	if (ret) { +		printf("%s: error reading the BOCO @%#x !!\n", +			__func__, reg); +		return ret; +	} +	regval |= flags; +	ret = i2c_write(BOCO_ADDR, reg, 1, ®val, 1); +	if (ret) { +		printf("%s: error writing the BOCO @%#x !!\n", +			__func__, reg); +		return ret; +	} + +	return 0; +} + +#define SPI_REG		0x06 +#define CFG_EEPROM	0x02 +#define FPGA_PROG	0x04 +#define FPGA_DONE	0x20 + +int trigger_fpga_config(void) +{ +	int ret = 0; + +	if (check_boco2()) { +		/* we have a BOCO2, this has to be triggered here */ + +		/* make sure the FPGA_can access the EEPROM */ +		ret = boco_clear_bits(SPI_REG, CFG_EEPROM); +		if (ret) +			return ret; + +		/* trigger the config start */ +		ret = boco_clear_bits(SPI_REG, FPGA_PROG); +		if (ret) +			return ret; + +		/* small delay for the pulse */ +		udelay(10); + +		/* up signal for pulse end */ +		ret = boco_set_bits(SPI_REG, FPGA_PROG); +		if (ret) +			return ret; + +	} else { +		/* we do it the old way, with the gpio pin */ +		kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1); +		kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0); +		/* small delay for the pulse */ +		udelay(10); +		kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN); +	} + +	return 0; +} + +int wait_for_fpga_config(void) +{ +	int ret = 0; +	u8 spictrl; +	u32 timeout = 20000; + +	if (!check_boco2()) { +		/* we do not have BOCO2, this is not really used */ +		return 0; +	} + +	printf("PCIe FPGA config:"); +	do { +		ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1); +		if (ret) { +			printf("%s: error reading the BOCO spictrl !!\n", +				__func__); +			return ret; +		} +		if (timeout-- == 0) { +			printf(" FPGA_DONE timeout\n"); +			return -EFAULT; +		} +		udelay(10); +	} while (!(spictrl & FPGA_DONE)); + +	printf(" done\n"); + +	return 0; +} + +#define PRST1		0x4 +#define BRIDGE_RST	0x4 + +int fpga_reset(void) +{ +	int ret = 0; + +	if (!check_boco2()) { +		/* we do not have BOCO2, this is not really used */ +		return 0; +	} + +	ret = boco_clear_bits(PRST1, BRIDGE_RST); +	if (ret) +		return ret; + +	/* small delay for the pulse */ +	udelay(10); + +	ret = boco_set_bits(PRST1, BRIDGE_RST); +	if (ret) +		return ret; + +	return 0; +} + +/* the FPGA was configured, we configure the BOCO2 so that the EEPROM + * is available from the Bobcat SPI bus */ +int toggle_eeprom_spi_bus(void) +{ +	int ret = 0; + +	if (!check_boco2()) { +		/* we do not have BOCO2, this is not really used */ +		return 0; +	} + +	ret = boco_set_bits(SPI_REG, CFG_EEPROM); +	if (ret) +		return ret; + +	return 0; +} + diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index daab27bbb..c8da823cb 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -268,12 +268,6 @@ int board_early_init_f(void)  	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);  	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);  #endif -#if defined(CONFIG_KM_RECONFIG_XLX) -	/* trigger the reconfiguration of the xilinx fpga */ -	kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1); -	kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0); -	kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN); -#endif  	return 0;  } @@ -282,6 +276,21 @@ int board_init(void)  	/* address of boot parameters */  	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100; +#if defined(CONFIG_KM_FPGA_CONFIG) +	trigger_fpga_config(); +#endif + +	return 0; +} + +int board_late_init(void) +{ +#if defined(CONFIG_KM_FPGA_CONFIG) +	wait_for_fpga_config(); +	fpga_reset(); +	toggle_eeprom_spi_bus(); +#endif +  	return 0;  } diff --git a/boards.cfg b/boards.cfg index db7902fa1..26c0a9904 100644 --- a/boards.cfg +++ b/boards.cfg @@ -141,7 +141,7 @@ dns325                       arm         arm926ejs   -                   d-link  lschlv2                      arm         arm926ejs   lsxl                buffalo        kirkwood    lsxl:LSCHLV2  lsxhl                        arm         arm926ejs   lsxl                buffalo        kirkwood    lsxl:LSXHL  km_kirkwood                  arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_KIRKWOOD,KM_DISABLE_PCI -km_kirkwood_pci              arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_KIRKWOOD_PCI,KM_RECONFIG_XLX +km_kirkwood_pci              arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_KIRKWOOD_PCI,KM_FPGA_CONFIG  kmnusa                       arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_NUSA  mgcoge3un                    arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_MGCOGE3UN  kmcoge5un                    arm         arm926ejs   km_arm              keymile        kirkwood    km_kirkwood:KM_COGE5UN diff --git a/include/configs/km/km_arm.h b/include/configs/km/km_arm.h index 60e2450d2..1a5f04bc7 100644 --- a/include/configs/km/km_arm.h +++ b/include/configs/km/km_arm.h @@ -313,4 +313,7 @@ int get_scl(void);  #define CONFIG_POST_EXTERNAL_WORD_FUNCS  #define CONFIG_CMD_DIAG +/* we do the whole PCIe FPGA config stuff here */ +#define	BOARD_LATE_INIT +  #endif /* _CONFIG_KM_ARM_H */ diff --git a/include/configs/km_kirkwood.h b/include/configs/km_kirkwood.h index 44a3e7a6e..0a61b7d9e 100644 --- a/include/configs/km_kirkwood.h +++ b/include/configs/km_kirkwood.h @@ -162,10 +162,12 @@  	MVGBE_SET_MII_SPEED_TO_100)  #endif -/* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */ -#define KM_XLX_PROGRAM_B_PIN    39 -  #ifdef CONFIG_KM_DISABLE_PCI  #undef  CONFIG_KIRKWOOD_PCIE_INIT  #endif + +#ifndef CONFIG_KM_FPGA_CONFIG +#undef  BOARD_LATE_INIT +#endif +  #endif /* _CONFIG_KM_KIRKWOOD */ |