diff options
| -rw-r--r-- | arch/arm/cpu/armv7/zynq/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/zynq/ddrc.c | 50 | ||||
| -rw-r--r-- | arch/arm/cpu/armv7/zynq/slcr.c | 2 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-zynq/hardware.h | 8 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-zynq/sys_proto.h | 1 | ||||
| -rw-r--r-- | board/xilinx/zynq/board.c | 19 | 
6 files changed, 80 insertions, 1 deletions
| diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile index e5494f748..de6b08157 100644 --- a/arch/arm/cpu/armv7/zynq/Makefile +++ b/arch/arm/cpu/armv7/zynq/Makefile @@ -14,6 +14,7 @@ LIB	= $(obj)lib$(SOC).o  COBJS-y	:= timer.o  COBJS-y	+= cpu.o +COBJS-y	+= ddrc.o  COBJS-y	+= slcr.o  COBJS	:= $(COBJS-y) diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c new file mode 100644 index 000000000..ba6a6aee5 --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/ddrc.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/hardware.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Control regsiter bitfield definitions */ +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK		0xC +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT	2 +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT	1 + +/* ECC scrub regsiter definitions */ +#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK	0x7 +#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED	0x4 + +void zynq_ddrc_init(void) +{ +	u32 width, ecctype; + +	width = readl(&ddrc_base->ddrc_ctrl); +	width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >> +					ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT; +	ecctype = (readl(&ddrc_base->ecc_scrub) & +		ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK); + +	/* ECC is enabled when memory is in 16bit mode and it is enabled */ +	if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) && +	    (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) { +		puts("Memory: ECC enabled\n"); +		/* +		 * Clear the first 1MB because it is not initialized from +		 * first stage bootloader. To get ECC to work all memory has +		 * been initialized by writing any value. +		 */ +		memset(0, 0, 1 * 1024 * 1024); +	} else { +		puts("Memory: ECC disabled\n"); +	} + +	if (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT) +		gd->ram_size /= 2; +} diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index e5fe99298..717ec65ae 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -70,7 +70,7 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)  		/* Configure GEM_RCLK_CTRL */  		writel(rclk, &slcr_base->gem0_rclk_ctrl);  	} - +	udelay(100000);  out:  	zynq_slcr_lock();  } diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index 081624e20..cd6967772 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -19,6 +19,7 @@  #define ZYNQ_I2C_BASEADDR1		0xE0005000  #define ZYNQ_SPI_BASEADDR0		0xE0006000  #define ZYNQ_SPI_BASEADDR1		0xE0007000 +#define ZYNQ_DDRC_BASEADDR		0xF8006000  /* Reflect slcr offsets */  struct slcr_regs { @@ -86,4 +87,11 @@ struct scu_regs {  #define scu_base ((struct scu_regs *)ZYNQ_SCU_BASEADDR) +struct ddrc_regs { +	u32 ddrc_ctrl; /* 0x0 */ +	u32 reserved[60]; +	u32 ecc_scrub; /* 0xF4 */ +}; +#define ddrc_base ((struct ddrc_regs *)ZYNQ_DDRC_BASEADDR) +  #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 19a4eec6a..110de9092 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -14,6 +14,7 @@ extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);  extern void zynq_slcr_devcfg_disable(void);  extern void zynq_slcr_devcfg_enable(void);  extern u32 zynq_slcr_get_idcode(void); +extern void zynq_ddrc_init(void);  /* Driver extern functions */  extern int zynq_sdhci_init(u32 regbase); diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index c173f0cc5..f7f1c59ac 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -65,6 +65,23 @@ int board_eth_init(bd_t *bis)  {  	u32 ret = 0; +#ifdef CONFIG_XILINX_AXIEMAC +	ret |= xilinx_axiemac_initialize(bis, XILINX_AXIEMAC_BASEADDR, +						XILINX_AXIDMA_BASEADDR); +#endif +#ifdef CONFIG_XILINX_EMACLITE +	u32 txpp = 0; +	u32 rxpp = 0; +# ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG +	txpp = 1; +# endif +# ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG +	rxpp = 1; +# endif +	ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR, +			txpp, rxpp); +#endif +  #if defined(CONFIG_ZYNQ_GEM)  # if defined(CONFIG_ZYNQ_GEM0)  	ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR0, @@ -100,5 +117,7 @@ int dram_init(void)  {  	gd->ram_size = CONFIG_SYS_SDRAM_SIZE; +	zynq_ddrc_init(); +  	return 0;  } |