[U-Boot] [PATCH 0/18] ARM zynq changes

Hi,
I am sending ARM zynq changes. This series is based on FPGA changes I have sent http://lists.denx.de/pipermail/u-boot/2014-April/178204.html (There is small dependency on some patches). My expectation is that fpga series will go to Tom's tree first.
Thanks, Michal
Michal Simek (12): ARM: zynq: Fix sparse warnings in slcr.c ARM: zynq: Fix sparse warning in ddrc.c ARM: zynq: Remove sparse warnings ARM: zynq: Do not use half memory size for ECC case ARM: zynq: Call zynq board_init() in SPL ARM: zynq: slcr: Fix incorrect commentary ARM: zynq: Setup correct slcr_lock value ARM: zynq: Fix building SPL without FPGA support ARM: zynq: Extend kernel image size to 60MB ARM: zynq: Add MIO detection code ARM: zynq: ehci: Added USB host driver support ARM: zynq: Extend maximum number of command arguments
Mike Looijmans (1): ARM: zynq: Fix bootmode mask
Siva Durga Prasad Paladugu (5): ARM: zynq: Added efuse status register base address ARM: zynq: Added USB host support for zynq boards ARM: zynq: Enable the FAT write capability ARM: zynq: Move USB/SD/MMC common FAT configs ARM: zynq: Enable EXT4 configs
arch/arm/cpu/armv7/zynq/cpu.c | 13 ++++ arch/arm/cpu/armv7/zynq/ddrc.c | 5 +- arch/arm/cpu/armv7/zynq/slcr.c | 87 ++++++++++++++++++++++-- arch/arm/cpu/armv7/zynq/spl.c | 7 ++ arch/arm/include/asm/arch-zynq/hardware.h | 13 +++- arch/arm/include/asm/arch-zynq/sys_proto.h | 2 + board/xilinx/zynq/board.c | 25 ++++--- drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-zynq.c | 104 +++++++++++++++++++++++++++++ include/configs/zynq-common.h | 32 +++++++-- include/configs/zynq_zc70x.h | 1 + include/configs/zynq_zed.h | 1 + 12 files changed, 268 insertions(+), 23 deletions(-) create mode 100644 drivers/usb/host/ehci-zynq.c
-- 1.8.2.3

Warnings: arch/arm/cpu/armv7/zynq/slcr.c:21:6: warning: symbol 'zynq_slcr_lock' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:27:6: warning: symbol 'zynq_slcr_unlock' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:34:6: warning: symbol 'zynq_slcr_cpu_reset' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:54:6: warning: symbol 'zynq_slcr_gem_clk_setup' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:81:6: warning: symbol 'zynq_slcr_devcfg_disable' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:94:6: warning: symbol 'zynq_slcr_devcfg_enable' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:107:5: warning: symbol 'zynq_slcr_get_boot_mode' was not declared. Should it be static? arch/arm/cpu/armv7/zynq/slcr.c:113:5: warning: symbol 'zynq_slcr_get_idcode' was not declared. Should it be static?
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/slcr.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index d7c1882..c326a4c 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <malloc.h> #include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> #include <asm/arch/clk.h>
#define SLCR_LOCK_MAGIC 0x767B -- 1.8.2.3

Warning: arch/arm/cpu/armv7/zynq/ddrc.c:43:24: warning: Using plain integer as NULL pointer
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/ddrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c index ba6a6ae..302654d 100644 --- a/arch/arm/cpu/armv7/zynq/ddrc.c +++ b/arch/arm/cpu/armv7/zynq/ddrc.c @@ -40,7 +40,7 @@ void zynq_ddrc_init(void) * first stage bootloader. To get ECC to work all memory has * been initialized by writing any value. */ - memset(0, 0, 1 * 1024 * 1024); + memset((void *)0, 0, 1 * 1024 * 1024); } else { puts("Memory: ECC disabled\n"); } -- 1.8.2.3

Warnings: board/xilinx/zynq/board.c:17:13: warning: symbol 'fpga' was not declared. Should it be static? board/xilinx/zynq/board.c:20:13: warning: symbol 'fpga010' was not declared. Should it be static? board/xilinx/zynq/board.c:21:13: warning: symbol 'fpga015' was not declared. Should it be static? board/xilinx/zynq/board.c:22:13: warning: symbol 'fpga020' was not declared. Should it be static? board/xilinx/zynq/board.c:23:13: warning: symbol 'fpga030' was not declared. Should it be static? board/xilinx/zynq/board.c:24:13: warning: symbol 'fpga045' was not declared. Should it be static? board/xilinx/zynq/board.c:25:13: warning: symbol 'fpga100' was not declared. Should it be static? board/xilinx/zynq/board.c:120:5: warning: symbol 'board_mmc_init' was not declared. Should it be static?
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
board/xilinx/zynq/board.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index c8cc2bc..5190938 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -6,6 +6,8 @@
#include <common.h> #include <fdtdec.h> +#include <fpga.h> +#include <mmc.h> #include <netdev.h> #include <zynqpl.h> #include <asm/arch/hardware.h> @@ -14,15 +16,15 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_FPGA -xilinx_desc fpga; +static xilinx_desc fpga;
/* It can be done differently */ -xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10); -xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15); -xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20); -xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30); -xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45); -xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100); +static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10); +static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15); +static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20); +static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30); +static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45); +static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100); #endif
int board_init(void) -- 1.8.2.3

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Added efuse status register base address. This register is used for determining whether efuse was blown or not. Also, added the zynq_get_silicon_version() to get the silicon version of the zynq board.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/cpu.c | 13 +++++++++++++ arch/arm/include/asm/arch-zynq/hardware.h | 9 +++++++++ arch/arm/include/asm/arch-zynq/sys_proto.h | 1 + 3 files changed, 23 insertions(+)
diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/cpu/armv7/zynq/cpu.c index 7626b5c..816d0c5 100644 --- a/arch/arm/cpu/armv7/zynq/cpu.c +++ b/arch/arm/cpu/armv7/zynq/cpu.c @@ -14,6 +14,9 @@ void lowlevel_init(void) { }
+#define ZYNQ_SILICON_VER_MASK 0xF0000000 +#define ZYNQ_SILICON_VER_SHIFT 28 + int arch_cpu_init(void) { zynq_slcr_unlock(); @@ -42,6 +45,16 @@ int arch_cpu_init(void) return 0; }
+unsigned int zynq_get_silicon_version(void) +{ + unsigned int ver; + + ver = (readl(&devcfg_base->mctrl) & + ZYNQ_SILICON_VER_MASK) >> ZYNQ_SILICON_VER_SHIFT; + + return ver; +} + void reset_cpu(ulong addr) { zynq_slcr_cpu_reset(); diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index 39184da..20f62bf 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -22,6 +22,7 @@ #define ZYNQ_SPI_BASEADDR0 0xE0006000 #define ZYNQ_SPI_BASEADDR1 0xE0007000 #define ZYNQ_DDRC_BASEADDR 0xF8006000 +#define ZYNQ_EFUSE_BASEADDR 0xF800D000
/* Bootmode setting values */ #define ZYNQ_BM_MASK 0xF @@ -130,4 +131,12 @@ struct ddrc_regs { }; #define ddrc_base ((struct ddrc_regs *)ZYNQ_DDRC_BASEADDR)
+struct efuse_reg { + u32 reserved1[4]; + u32 status; + u32 reserved2[3]; +}; + +#define efuse_base ((struct efuse_reg *)ZYNQ_EFUSE_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 a68e1b3..2445a04 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -16,6 +16,7 @@ extern void zynq_slcr_devcfg_enable(void); extern u32 zynq_slcr_get_boot_mode(void); extern u32 zynq_slcr_get_idcode(void); extern void zynq_ddrc_init(void); +extern unsigned int zynq_get_silicon_version(void);
/* Driver extern functions */ extern int zynq_sdhci_init(u32 regbase); -- 1.8.2.3

Memory size should be specified without ECC place. If you need to have half memory size, please change u-boot configuration.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/ddrc.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c index 302654d..e0ed3bf 100644 --- a/arch/arm/cpu/armv7/zynq/ddrc.c +++ b/arch/arm/cpu/armv7/zynq/ddrc.c @@ -44,7 +44,4 @@ void zynq_ddrc_init(void) } else { puts("Memory: ECC disabled\n"); } - - if (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT) - gd->ram_size /= 2; } -- 1.8.2.3

From: Michal Simek monstr@monstr.eu
Call board_init() if SPL is configured with CONFIG_SPL_BOARD_INIT.
Signed-off-by: Michal Simek monstr@monstr.eu Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/spl.c | 7 +++++++ include/configs/zynq-common.h | 1 + 2 files changed, 8 insertions(+)
diff --git a/arch/arm/cpu/armv7/zynq/spl.c b/arch/arm/cpu/armv7/zynq/spl.c index fcad762..c3ea221 100644 --- a/arch/arm/cpu/armv7/zynq/spl.c +++ b/arch/arm/cpu/armv7/zynq/spl.c @@ -28,6 +28,13 @@ void board_init_f(ulong dummy) board_init_r(NULL, 0); }
+#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void) +{ + board_init(); +} +#endif + u32 spl_boot_device(void) { u32 mode; diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 731e69b..2080a61 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -235,6 +235,7 @@ #define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_BOARD_INIT
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot-spl.lds"
-- 1.8.2.3

Fix c&p error in zynq_slcr_devcfg_enable() commentary and extending it with description according to Zynq TRM also in zynq_slcr_devcfg_disable().
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/slcr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index c326a4c..1ff1eac 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -83,7 +83,7 @@ void zynq_slcr_devcfg_disable(void) { zynq_slcr_unlock();
- /* Disable AXI interface */ + /* Disable AXI interface by asserting FPGA resets */ writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl);
/* Set Level Shifters DT618760 */ @@ -99,7 +99,7 @@ void zynq_slcr_devcfg_enable(void) /* Set Level Shifters DT618760 */ writel(0xF, &slcr_base->lvl_shftr_en);
- /* Disable AXI interface */ + /* Enable AXI interface by de-asserting FPGA resets */ writel(0x0, &slcr_base->fpga_rst_ctrl);
zynq_slcr_lock(); -- 1.8.2.3

The driver should setup slcr state according to slcr operations.
Reported-by: Andrey Filippov andrey@elphel.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/slcr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index 1ff1eac..5ba58fa 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -21,14 +21,18 @@ static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
void zynq_slcr_lock(void) { - if (!slcr_lock) + if (!slcr_lock) { writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); + slcr_lock = 1; + } }
void zynq_slcr_unlock(void) { - if (slcr_lock) + if (slcr_lock) { writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); + slcr_lock = 0; + } }
/* Reset the entire system */ -- 1.8.2.3

From: Mike Looijmans mike.looijmans@topic.nl
Bootmode mask was defined as 0x0F, but documentation mentions 0x07. Experiments show that bit "3" is the JTAG chain configuration. Change the mask to "7" to allow systems with a different chain configuration to boot correctly.
Signed-off-by: Mike Looijmans mike.looijmans@topic.nl Signed-off-by: Michal Simek michal.simek@xilinx.com Acked-by: Siva Durga Prasad Paladugu sivadur@xilinx.com ---
arch/arm/include/asm/arch-zynq/hardware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index 20f62bf..a9d091f 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -25,7 +25,7 @@ #define ZYNQ_EFUSE_BASEADDR 0xF800D000
/* Bootmode setting values */ -#define ZYNQ_BM_MASK 0xF +#define ZYNQ_BM_MASK 0x7 #define ZYNQ_BM_NOR 0x2 #define ZYNQ_BM_SD 0x5 #define ZYNQ_BM_JTAG 0x0 -- 1.8.2.3

When CONFIG_FPGA is defined but CONFIG_SPL_FPGA is not, the build fails: board.c: In function 'board_init': board.c:41:3: error: 'fpga' undeclared (first use in this function) fpga = fpga010;
Fix this by expanding the "#if.." around this block to match the other FPGA checks and don't compile this block when buildign for SPL without FPGA support.
Tested a bootloader that had CONFIG_FPGA defined without CONFIG_SPL_FPGA, this now compiles without errors and loading FPGA from u-boot works.
Signed-off-by: Mike Looijmans mike.looijmans@topic.nl Signed-off-by: Michal Simek michal.simek@xilinx.com ---
board/xilinx/zynq/board.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 5190938..258632e 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -15,7 +15,8 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_FPGA +#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ + (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) static xilinx_desc fpga;
/* It can be done differently */ @@ -29,7 +30,8 @@ static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
int board_init(void) { -#ifdef CONFIG_FPGA +#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ + (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) u32 idcode;
idcode = zynq_slcr_get_idcode(); @@ -56,7 +58,8 @@ int board_init(void) } #endif
-#ifdef CONFIG_FPGA +#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ + (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) fpga_init(); fpga_add(fpga_xilinx, &fpga); #endif -- 1.8.2.3

Extend max kernel image size. Gunzip is checking this value. If kernel is larger, message below is shown.
Uncompressing Kernel Image ... Error: inflate() returned -5 GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 2080a61..8ee78e4 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -209,7 +209,7 @@ #define CONFIG_RSA
/* Extend size of kernel image for uncompression */ -#define CONFIG_SYS_BOOTM_LEN (20 * 1024 * 1024) +#define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024)
/* Boot FreeBSD/vxWorks from an ELF image */ #if defined(CONFIG_ZYNQ_BOOT_FREEBSD) -- 1.8.2.3

From: Michal Simek monstr@monstr.eu
Add run-time MIO pin detection to get actual pin configuration for specific periphery.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/slcr.c | 50 ++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-zynq/sys_proto.h | 1 + 2 files changed, 51 insertions(+)
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index 5ba58fa..51894f9 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -17,6 +17,26 @@ #define SLCR_IDCODE_MASK 0x1F000 #define SLCR_IDCODE_SHIFT 12
+/* + * zynq_slcr_mio_get_status - Get the status of MIO peripheral. + * + * @peri_name: Name of the peripheral for checking MIO status + * @get_pins: Pointer to array of get pin for this peripheral + * @num_pins: Number of pins for this peripheral + * @mask: Mask value + * @check_val: Required check value to get the status of periph + */ +struct zynq_slcr_mio_get_status { + const char *peri_name; + const int *get_pins; + int num_pins; + u32 mask; + u32 check_val; +}; + +static const struct zynq_slcr_mio_get_status mio_periphs[] = { +}; + static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
void zynq_slcr_lock(void) @@ -120,3 +140,33 @@ u32 zynq_slcr_get_idcode(void) return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> SLCR_IDCODE_SHIFT; } + +/* + * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral. + * + * @periph: Name of the peripheral + * + * Returns count to indicate the number of pins configured for the + * given @periph. + */ +int zynq_slcr_get_mio_pin_status(const char *periph) +{ + const struct zynq_slcr_mio_get_status *mio_ptr; + int val, i, j; + int mio = 0; + + for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) { + if (strcmp(periph, mio_periphs[i].peri_name) == 0) { + mio_ptr = &mio_periphs[i]; + for (j = 0; j < mio_ptr->num_pins; j++) { + val = readl(&slcr_base->mio_pin + [mio_ptr->get_pins[j]]); + if ((val & mio_ptr->mask) == mio_ptr->check_val) + mio++; + } + break; + } + } + + return mio; +} diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 2445a04..53c30ec 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -15,6 +15,7 @@ extern void zynq_slcr_devcfg_disable(void); extern void zynq_slcr_devcfg_enable(void); extern u32 zynq_slcr_get_boot_mode(void); extern u32 zynq_slcr_get_idcode(void); +extern int zynq_slcr_get_mio_pin_status(const char *periph); extern void zynq_ddrc_init(void); extern unsigned int zynq_get_silicon_version(void);
-- 1.8.2.3

From: Michal Simek monstr@monstr.eu
Added USB host driver for zynq.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv7/zynq/slcr.c | 24 +++++++ arch/arm/include/asm/arch-zynq/hardware.h | 2 + drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-zynq.c | 104 ++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 drivers/usb/host/ehci-zynq.c
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index 51894f9..934ccc3 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -14,6 +14,8 @@ #define SLCR_LOCK_MAGIC 0x767B #define SLCR_UNLOCK_MAGIC 0xDF0D
+#define SLCR_USB_L1_SEL 0x04 + #define SLCR_IDCODE_MASK 0x1F000 #define SLCR_IDCODE_SHIFT 12
@@ -34,7 +36,29 @@ struct zynq_slcr_mio_get_status { u32 check_val; };
+static const int usb0_pins[] = { + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 +}; + +static const int usb1_pins[] = { + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 +}; + static const struct zynq_slcr_mio_get_status mio_periphs[] = { + { + "usb0", + usb0_pins, + ARRAY_SIZE(usb0_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, + { + "usb1", + usb1_pins, + ARRAY_SIZE(usb1_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, };
static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index a9d091f..2aede0c 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -23,6 +23,8 @@ #define ZYNQ_SPI_BASEADDR1 0xE0007000 #define ZYNQ_DDRC_BASEADDR 0xF8006000 #define ZYNQ_EFUSE_BASEADDR 0xF800D000 +#define ZYNQ_USB_BASEADDR0 0xE0002000 +#define ZYNQ_USB_BASEADDR1 0xE0003000
/* Bootmode setting values */ #define ZYNQ_BM_MASK 0x7 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 578b097..bf87204 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o +obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
# xhci obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o diff --git a/drivers/usb/host/ehci-zynq.c b/drivers/usb/host/ehci-zynq.c new file mode 100644 index 0000000..7770d05 --- /dev/null +++ b/drivers/usb/host/ehci-zynq.c @@ -0,0 +1,104 @@ +/* + * (C) Copyright 2014, Xilinx, Inc + * + * USB Low level initialization(Specific to zynq) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <usb.h> +#include <usb/ehci-fsl.h> +#include <usb/ulpi.h> + +#include "ehci.h" + +#define ZYNQ_USB_USBCMD_RST 0x0000002 +#define ZYNQ_USB_USBCMD_STOP 0x0000000 +#define ZYNQ_USB_NUM_MIO 12 + +/* + * Create the appropriate control structures to manage + * a new EHCI host controller. + */ +int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, + struct ehci_hcor **hcor) +{ + struct usb_ehci *ehci; + struct ulpi_viewport ulpi_vp; + int ret, mio_usb; + /* Used for writing the ULPI data address */ + struct ulpi_regs *ulpi = (struct ulpi_regs *)0; + + if (!index) { + mio_usb = zynq_slcr_get_mio_pin_status("usb0"); + if (mio_usb != ZYNQ_USB_NUM_MIO) { + printf("usb0 wrong num MIO: %d, Index %d\n", mio_usb, + index); + return -1; + } + ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; + } else { + mio_usb = zynq_slcr_get_mio_pin_status("usb1"); + if (mio_usb != ZYNQ_USB_NUM_MIO) { + printf("usb1 wrong num MIO: %d, Index %d\n", mio_usb, + index); + return -1; + } + ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; + } + + *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + *hcor = (struct ehci_hcor *)((uint32_t) *hccr + + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + + ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint; + ulpi_vp.port_num = 0; + + ret = ulpi_init(&ulpi_vp); + if (ret) { + puts("zynq ULPI viewport init failed\n"); + return -1; + } + + /* ULPI set flags */ + ulpi_write(&ulpi_vp, &ulpi->otg_ctrl, + ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN | + ULPI_OTG_EXTVBUSIND); + ulpi_write(&ulpi_vp, &ulpi->function_ctrl, + ULPI_FC_FULL_SPEED | ULPI_FC_OPMODE_NORMAL | + ULPI_FC_SUSPENDM); + ulpi_write(&ulpi_vp, &ulpi->iface_ctrl, 0); + + /* Set VBus */ + ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, + ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); + + return 0; +} + +/* + * Destroy the appropriate control structures corresponding + * the the EHCI host controller. + */ +int ehci_hcd_stop(int index) +{ + struct usb_ehci *ehci; + + if (!index) + ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR0; + else + ehci = (struct usb_ehci *)ZYNQ_USB_BASEADDR1; + + /* Stop controller */ + writel(ZYNQ_USB_USBCMD_STOP, &ehci->usbcmd); + udelay(1000); + + /* Initiate controller reset */ + writel(ZYNQ_USB_USBCMD_RST, &ehci->usbcmd); + + return 0; +} -- 1.8.2.3

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Added configs to support USB host for zynq boards. Also added a command usbboot to boot from usb.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 20 +++++++++++++++++++- include/configs/zynq_zc70x.h | 1 + include/configs/zynq_zed.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 8ee78e4..bcc476e 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -89,6 +89,18 @@ # define CONFIG_DOS_PARTITION #endif
+#ifdef CONFIG_ZYNQ_USB +# define CONFIG_USB_EHCI +# define CONFIG_CMD_USB +# define CONFIG_USB_STORAGE +# define CONFIG_SUPPORT_VFAT +# define CONFIG_USB_EHCI_ZYNQ +# define CONFIG_USB_ULPI_VIEWPORT +# define CONFIG_USB_ULPI +# define CONFIG_EHCI_IS_TDI +# define CONFIG_USB_MAX_CONTROLLER_COUNT 2 +#endif + #define CONFIG_SYS_I2C_ZYNQ /* I2C */ #if defined(CONFIG_SYS_I2C_ZYNQ) @@ -150,7 +162,13 @@ "bootm ${load_addr}\0" \ "jtagboot=echo TFTPing FIT to RAM... && " \ "tftpboot ${load_addr} ${fit_image} && " \ - "bootm ${load_addr}\0" + "bootm ${load_addr}\0" \ + "usbboot=if usb start; then " \ + "echo Copying FIT from USB to RAM... && " \ + "fatload usb 0 ${load_addr} ${fit_image} && " \ + "bootm ${load_addr}\0" \ + "fi\0" + #define CONFIG_BOOTCOMMAND "run $modeboot" #define CONFIG_BOOTDELAY 3 /* -1 to Disable autoboot */ #define CONFIG_SYS_LOAD_ADDR 0 /* default? */ diff --git a/include/configs/zynq_zc70x.h b/include/configs/zynq_zc70x.h index de0e241..291a5fe 100644 --- a/include/configs/zynq_zc70x.h +++ b/include/configs/zynq_zc70x.h @@ -19,6 +19,7 @@ #define CONFIG_SYS_NO_FLASH
#define CONFIG_ZYNQ_SDHCI0 +#define CONFIG_ZYNQ_USB #define CONFIG_ZYNQ_I2C0 #define CONFIG_ZYNQ_EEPROM #define CONFIG_ZYNQ_BOOT_FREEBSD diff --git a/include/configs/zynq_zed.h b/include/configs/zynq_zed.h index 274140c..ce17d40 100644 --- a/include/configs/zynq_zed.h +++ b/include/configs/zynq_zed.h @@ -18,6 +18,7 @@
#define CONFIG_SYS_NO_FLASH
+#define CONFIG_ZYNQ_USB #define CONFIG_ZYNQ_SDHCI0 #define CONFIG_ZYNQ_BOOT_FREEBSD #define CONFIG_DEFAULT_DEVICE_TREE zynq-zed -- 1.8.2.3

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Enable the FAT write capability for SD/MMC write functionality.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index bcc476e..1cfc963 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -86,6 +86,7 @@ # define CONFIG_CMD_FAT # define CONFIG_SUPPORT_VFAT # define CONFIG_CMD_EXT2 +# define CONFIG_FAT_WRITE # define CONFIG_DOS_PARTITION #endif
-- 1.8.2.3

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Moved the USB/SD/MMC common FAT configs separately to avoid redefinition warnings.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 1cfc963..0a7d104 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -83,18 +83,12 @@ # define CONFIG_SDHCI # define CONFIG_ZYNQ_SDHCI # define CONFIG_CMD_MMC -# define CONFIG_CMD_FAT -# define CONFIG_SUPPORT_VFAT -# define CONFIG_CMD_EXT2 -# define CONFIG_FAT_WRITE -# define CONFIG_DOS_PARTITION #endif
#ifdef CONFIG_ZYNQ_USB # define CONFIG_USB_EHCI # define CONFIG_CMD_USB # define CONFIG_USB_STORAGE -# define CONFIG_SUPPORT_VFAT # define CONFIG_USB_EHCI_ZYNQ # define CONFIG_USB_ULPI_VIEWPORT # define CONFIG_USB_ULPI @@ -102,6 +96,14 @@ # define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif
+#if defined(CONFIG_ZYNQ_SDHCI) || defined(CONFIG_ZYNQ_USB) +# define CONFIG_SUPPORT_VFAT +# define CONFIG_CMD_FAT +# define CONFIG_CMD_EXT2 +# define CONFIG_FAT_WRITE +# define CONFIG_DOS_PARTITION +#endif + #define CONFIG_SYS_I2C_ZYNQ /* I2C */ #if defined(CONFIG_SYS_I2C_ZYNQ) -- 1.8.2.3

From: Siva Durga Prasad Paladugu siva.durga.paladugu@xilinx.com
Enabled the EXT4 configs.
Signed-off-by: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 0a7d104..09d6c55 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -102,6 +102,8 @@ # define CONFIG_CMD_EXT2 # define CONFIG_FAT_WRITE # define CONFIG_DOS_PARTITION +# define CONFIG_CMD_EXT4 +# define CONFIG_CMD_EXT4_WRITE #endif
#define CONFIG_SYS_I2C_ZYNQ -- 1.8.2.3

15 was too small for variables stored in file on MMC.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
include/configs/zynq-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 09d6c55..d2149b3 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -188,7 +188,7 @@ #define CONFIG_SYS_LONGHELP #define CONFIG_CLOCKS #define CONFIG_CMD_CLK -#define CONFIG_SYS_MAXARGS 15 /* max number of command args */ +#define CONFIG_SYS_MAXARGS 32 /* max number of command args */ #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ sizeof(CONFIG_SYS_PROMPT) + 16) -- 1.8.2.3
participants (1)
-
Michal Simek