From 371b9e9c394d7d96935afbc6fae318fde2fa2760 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Sun, 17 Jan 2016 18:23:45 +0100 Subject: ARM: sheevaplug: correct nand partition layout Commit 1e3d640316 (ARM: sheevaplug: redefine MTDPARTS) changed the partition layout (without any description why), but didn't change the offset/size to load the kernel from or the root=/dev/mtdblockX in the bootargs. The 3MB forseen for a kernel is furthermore too little. A 4.4 build of mvebu_v5_defconfig is 3.6MB: -rw-r--r-- 1 peko peko 3.6M Jan 16 20:24 uImage.kirkwood-sheevaplug When device tree support for sheevaplug was added to the kernel in commit ee514b381e (ARM: Kirkwood: Add dts files for Sheevaplug and eSATA Sheevaplug) a default flash partition layout (used if mtdparts= isn't passed on the command line / CONFIG_MTD_CMDLINE_PARTS isn't enabled) with 1MB for u-boot / environment, 4MB for the kernel and the rest for the rootfs, so use that layout here and adjust the kernel loading to match. Signed-off-by: Peter Korsgaard Signed-off-by: Stefan Roese --- include/configs/sheevaplug.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h index c529636a66d..f9fb9bc9afb 100644 --- a/include/configs/sheevaplug.h +++ b/include/configs/sheevaplug.h @@ -64,12 +64,12 @@ #define CONFIG_MTDPARTS \ "orion_nand:512K(uboot)," \ - "512K(env),1M(script),6M(kernel)," \ - "12M(ramdisk),4M(spare),-(rootfs)\0" + "512K(env),4M(kernel)," \ + "-(rootfs)\0" #define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console" \ "=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ - "x_bootcmd_kernel=nand read 0x6400000 0x100000 0x300000\0" \ + "x_bootcmd_kernel=nand read 0x6400000 0x100000 0x400000\0" \ "x_bootcmd_usb=usb start\0" \ "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" -- cgit v1.3.1 From ff9c4c535a8b722c54d45e77aa083fa08552341d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 12 Feb 2016 13:48:02 +0100 Subject: fpga: altera: Add StratixV support This patch adds support for programming of the StratixV FPGAs. Programming is done in this case (board theadorable) via SPI. The board may provide board specific code for bitstream programming. This StratixV support will be used by the theadorable board. Signed-off-by: Stefan Roese Cc: Tom Rini Signed-off-by: Stefan Roese --- drivers/fpga/Makefile | 1 + drivers/fpga/altera.c | 3 ++ drivers/fpga/stratixv.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ include/altera.h | 20 ++++++++++ 4 files changed, 127 insertions(+) create mode 100644 drivers/fpga/stratixv.c (limited to 'include') diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 6aa24d43590..fec3fecbdfb 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -17,5 +17,6 @@ obj-y += altera.o obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o +obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o endif diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c index a5bfe5dce19..135a3572a83 100644 --- a/drivers/fpga/altera.c +++ b/drivers/fpga/altera.c @@ -37,6 +37,9 @@ static const struct altera_fpga { { Altera_StratixII, "StratixII", StratixII_load, StratixII_dump, StratixII_info }, #endif +#if defined(CONFIG_FPGA_STRATIX_V) + { Altera_StratixV, "StratixV", stratixv_load, NULL, NULL }, +#endif #if defined(CONFIG_FPGA_SOCFPGA) { Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL }, #endif diff --git a/drivers/fpga/stratixv.c b/drivers/fpga/stratixv.c new file mode 100644 index 00000000000..cc035eb2a14 --- /dev/null +++ b/drivers/fpga/stratixv.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +/* Write the RBF data to FPGA via SPI */ +static int program_write(int spi_bus, int spi_dev, const void *rbf_data, + unsigned long rbf_size) +{ + struct spi_slave *slave; + int ret; + + debug("%s (%d): data=%p size=%ld\n", + __func__, __LINE__, rbf_data, rbf_size); + + /* FIXME: How to get the max. SPI clock and SPI mode? */ + slave = spi_setup_slave(spi_bus, spi_dev, 27777777, SPI_MODE_3); + if (!slave) + return -1; + + if (spi_claim_bus(slave)) + return -1; + + ret = spi_xfer(slave, rbf_size * 8, rbf_data, (void *)rbf_data, + SPI_XFER_BEGIN | SPI_XFER_END); + + spi_release_bus(slave); + + return ret; +} + +/* + * This is the interface used by FPGA driver. + * Return 0 for sucess, non-zero for error. + */ +int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) +{ + altera_board_specific_func *pfns = desc->iface_fns; + int cookie = desc->cookie; + int spi_bus; + int spi_dev; + int ret = 0; + + if ((u32)rbf_data & 0x3) { + puts("FPGA: Unaligned data, realign to 32bit boundary.\n"); + return -EINVAL; + } + + /* Run the pre configuration function if there is one */ + if (pfns->pre) + (pfns->pre)(cookie); + + /* Establish the initial state */ + if (pfns->config) { + /* De-assert nCONFIG */ + (pfns->config)(false, true, cookie); + + /* nConfig minimum low pulse width is 2us */ + udelay(200); + + /* Assert nCONFIG */ + (pfns->config)(true, true, cookie); + + /* nCONFIG high to first rising clock on DCLK min 1506 us */ + udelay(1600); + } + + /* Write the RBF data to FPGA */ + if (pfns->write) { + /* + * Use board specific data function to write bitstream + * into the FPGA + */ + ret = (pfns->write)(rbf_data, rbf_size, true, cookie); + } else { + /* + * Use common SPI functions to write bitstream into the + * FPGA + */ + spi_bus = COOKIE2SPI_BUS(cookie); + spi_dev = COOKIE2SPI_DEV(cookie); + ret = program_write(spi_bus, spi_dev, rbf_data, rbf_size); + } + if (ret) + return ret; + + /* Check done pin */ + if (pfns->done) { + ret = (pfns->done)(cookie); + + if (ret) + printf("Error: DONE not set (ret=%d)!\n", ret); + } + + return ret; +} diff --git a/include/altera.h b/include/altera.h index c2991ad8000..48d3eb73c98 100644 --- a/include/altera.h +++ b/include/altera.h @@ -10,6 +10,19 @@ #ifndef _ALTERA_H_ #define _ALTERA_H_ +/* + * For the StratixV FPGA programming via SPI, the following + * information is coded in the 32bit cookie: + * Bit 31 ... Bit 0 + * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin + */ +#define FPGA_COOKIE(bus, dev, config, done) \ + (((bus) << 24) | ((dev) << 16) | ((config) << 8) | (done)) +#define COOKIE2SPI_BUS(c) (((c) >> 24) & 0xff) +#define COOKIE2SPI_DEV(c) (((c) >> 16) & 0xff) +#define COOKIE2CONFIG(c) (((c) >> 8) & 0xff) +#define COOKIE2DONE(c) ((c) & 0xff) + enum altera_iface { /* insert all new types after this */ min_altera_iface_type, @@ -40,6 +53,8 @@ enum altera_family { Altera_CYC2, /* StratixII Family */ Altera_StratixII, + /* StratixV Family */ + Altera_StratixV, /* SoCFPGA Family */ Altera_SoCFPGA, @@ -89,6 +104,7 @@ typedef struct { Altera_done_fn done; Altera_clk_fn clk; Altera_data_fn data; + Altera_write_fn write; Altera_abort_fn abort; Altera_post_fn post; } altera_board_specific_func; @@ -97,4 +113,8 @@ typedef struct { int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); #endif +#ifdef CONFIG_FPGA_STRATIX_V +int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size); +#endif + #endif /* _ALTERA_H_ */ -- cgit v1.3.1 From aea02abec59e8ea8e78c7926162c2b0f6073f32c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 12 Feb 2016 14:24:07 +0100 Subject: arm: mvebu: theadorable: Add StratixV FPGA programming support This patch adds support for Altera StratixV bitstream programming. 2 FPGAs are connected to the SPI busses. This patch uses board specific write code to program the bitstream via SPI direct write mode. Signed-off-by: Stefan Roese Cc: Luka Perkov Signed-off-by: Stefan Roese --- arch/arm/dts/armada-xp-theadorable.dts | 21 ++++ board/theadorable/Makefile | 1 + board/theadorable/fpga.c | 179 +++++++++++++++++++++++++++++++++ board/theadorable/theadorable.c | 13 +++ board/theadorable/theadorable.h | 12 +++ configs/theadorable_debug_defconfig | 3 +- configs/theadorable_defconfig | 2 +- include/configs/theadorable.h | 5 + 8 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 board/theadorable/fpga.c create mode 100644 board/theadorable/theadorable.h (limited to 'include') diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index cf1be2a3d4e..7087ccfc2f0 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -69,6 +69,7 @@ aliases { spi0 = &spi0; + spi1 = &spi1; ethernet0 = ð0; }; @@ -137,6 +138,26 @@ reg = <0>; /* Chip select 0 */ spi-max-frequency = <27777777>; }; + + fpga@1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-generic-device"; + reg = <1>; /* Chip select 1 */ + spi-max-frequency = <27777777>; + }; + }; + + spi1: spi@10680 { + status = "okay"; + + fpga@2 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-generic-device"; + reg = <2>; /* Chip select 2 */ + spi-max-frequency = <27777777>; + }; }; }; }; diff --git a/board/theadorable/Makefile b/board/theadorable/Makefile index 9d5b39e6964..ef5a519ada9 100644 --- a/board/theadorable/Makefile +++ b/board/theadorable/Makefile @@ -5,3 +5,4 @@ # obj-y := theadorable.o +obj-y += fpga.o diff --git a/board/theadorable/fpga.c b/board/theadorable/fpga.c new file mode 100644 index 00000000000..6f068c38ada --- /dev/null +++ b/board/theadorable/fpga.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "theadorable.h" + +/* + * FPGA programming support + */ +static int fpga_pre_fn(int cookie) +{ + int gpio_config = COOKIE2CONFIG(cookie); + int gpio_done = COOKIE2DONE(cookie); + int ret; + + debug("%s (%d): cookie=%08x gpio_config=%d gpio_done=%d\n", + __func__, __LINE__, cookie, gpio_config, gpio_done); + + /* Configure config pin */ + /* Set to output */ + ret = gpio_request(gpio_config, "CONFIG"); + if (ret < 0) + return ret; + gpio_direction_output(gpio_config, 1); + + /* Configure done pin */ + /* Set to input */ + ret = gpio_request(gpio_done, "DONE"); + if (ret < 0) + return ret; + + gpio_direction_input(gpio_done); + + return 0; +} + +static int fpga_config_fn(int assert, int flush, int cookie) +{ + int gpio_config = COOKIE2CONFIG(cookie); + + debug("%s (%d): cookie=%08x gpio_config=%d\n", + __func__, __LINE__, cookie, gpio_config); + + if (assert) + gpio_set_value(gpio_config, 1); + else + gpio_set_value(gpio_config, 0); + + return 0; +} + +static int fpga_write_fn(const void *buf, size_t len, int flush, int cookie) +{ + int spi_bus = COOKIE2SPI_BUS(cookie); + int spi_dev = COOKIE2SPI_DEV(cookie); + struct kwspi_registers *reg; + u32 control_reg; + u32 config_reg; + void *dst; + + /* + * Write data to FPGA attached to SPI bus via SPI direct write. + * This results in the fastest and easiest way to program the + * bitstream into the FPGA. + */ + debug("%s (%d): cookie=%08x spi_bus=%d spi_dev=%d\n", + __func__, __LINE__, cookie, spi_bus, spi_dev); + + if (spi_bus == 0) { + reg = (struct kwspi_registers *)MVEBU_REGISTER(0x10600); + dst = (void *)SPI_BUS0_DEV1_BASE; + } else { + reg = (struct kwspi_registers *)MVEBU_REGISTER(0x10680); + dst = (void *)SPI_BUS1_DEV2_BASE; + } + + /* Configure SPI controller for direct access mode */ + control_reg = readl(®->ctrl); + config_reg = readl(®->cfg); + writel(0x00000214, ®->cfg); /* 27MHz clock */ + writel(0x00000000, ®->dw_cfg); /* don't de-asset CS */ + writel(KWSPI_CSN_ACT, ®->ctrl); /* activate CS */ + + /* Copy data to the SPI direct mapped window */ + memcpy(dst, buf, len); + + /* Restore original register values */ + writel(control_reg, ®->ctrl); + writel(config_reg, ®->cfg); + + return 0; +} + +/* Returns the state of CONF_DONE Pin */ +static int fpga_done_fn(int cookie) +{ + int gpio_done = COOKIE2DONE(cookie); + unsigned long ts; + + debug("%s (%d): cookie=%08x gpio_done=%d\n", + __func__, __LINE__, cookie, gpio_done); + + ts = get_timer(0); + do { + if (gpio_get_value(gpio_done)) + return 0; + } while (get_timer(ts) < 1000); + + /* timeout so return error */ + return -ENODEV; +} + +static altera_board_specific_func stratixv_fns = { + .pre = fpga_pre_fn, + .config = fpga_config_fn, + .write = fpga_write_fn, + .done = fpga_done_fn, +}; + +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_StratixV, + /* Interface type */ + passive_serial, + /* No limitation as additional data will be ignored */ + -1, + /* Device function table */ + (void *)&stratixv_fns, + /* Base interface address specified in driver */ + NULL, + /* Cookie implementation */ + /* + * In this 32bit word the following information is coded: + * Bit 31 ... Bit 0 + * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin + */ + FPGA_COOKIE(0, 1, 26, 7) + }, + { + /* Family */ + Altera_StratixV, + /* Interface type */ + passive_serial, + /* No limitation as additional data will be ignored */ + -1, + /* Device function table */ + (void *)&stratixv_fns, + /* Base interface address specified in driver */ + NULL, + /* Cookie implementation */ + /* + * In this 32bit word the following information is coded: + * Bit 31 ... Bit 0 + * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin + */ + FPGA_COOKIE(1, 2, 29, 9) + }, +}; + +/* Add device descriptor to FPGA device table */ +void board_fpga_add(void) +{ + int i; + + fpga_init(); + for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) + fpga_add(fpga_altera, &altera_fpga[i]); +} diff --git a/board/theadorable/theadorable.c b/board/theadorable/theadorable.c index 0e232656fc9..ee88a98a241 100644 --- a/board/theadorable/theadorable.c +++ b/board/theadorable/theadorable.c @@ -8,9 +8,11 @@ #include #include #include +#include #ifdef CONFIG_NET #include #endif +#include "theadorable.h" #include "../drivers/ddr/marvell/axp/ddr3_hw_training.h" #include "../arch/arm/mach-mvebu/serdes/axp/high_speed_env_spec.h" @@ -136,6 +138,15 @@ int board_init(void) /* adress of boot parameters */ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; + /* + * Map SPI devices via MBUS so that they can be accessed via + * the SPI direct access mode + */ + mbus_dt_setup_win(&mbus_state, SPI_BUS0_DEV1_BASE, SPI_BUS0_DEV1_SIZE, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPI0_CS1); + mbus_dt_setup_win(&mbus_state, SPI_BUS1_DEV2_BASE, SPI_BUS0_DEV1_SIZE, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPI1_CS2); + return 0; } @@ -143,6 +154,8 @@ int checkboard(void) { puts("Board: theadorable\n"); + board_fpga_add(); + return 0; } diff --git a/board/theadorable/theadorable.h b/board/theadorable/theadorable.h new file mode 100644 index 00000000000..89fe1179a48 --- /dev/null +++ b/board/theadorable/theadorable.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2016 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Base addresses for the SPI direct access mode */ +#define SPI_BUS0_DEV1_BASE 0xe0000000 +#define SPI_BUS0_DEV1_SIZE (1 << 20) +#define SPI_BUS1_DEV2_BASE (SPI_BUS0_DEV1_BASE + SPI_BUS0_DEV1_SIZE) + +void board_fpga_add(void); diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index 62a6ee6663b..054038a03be 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_MVEBU=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_THEADORABLE=y +CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="armada-xp-theadorable" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y @@ -10,7 +11,7 @@ CONFIG_FIT=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_SF=y CONFIG_CMD_USB=y -# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_OF_TRANSLATE=y diff --git a/configs/theadorable_defconfig b/configs/theadorable_defconfig index 4d5f3b0a0aa..9a6abf2f7e3 100644 --- a/configs/theadorable_defconfig +++ b/configs/theadorable_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_MVEBU=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_THEADORABLE=y +CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="armada-xp-theadorable" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y @@ -9,7 +10,6 @@ CONFIG_FIT=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_CMD_SF=y -# CONFIG_CMD_FPGA is not set # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NET is not set # CONFIG_CMD_NFS is not set diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h index 9f186add71f..a4bcf212108 100644 --- a/include/configs/theadorable.h +++ b/include/configs/theadorable.h @@ -114,6 +114,11 @@ #define CONFIG_VGA_AS_SINGLE_DEVICE #define CONFIG_CMD_BMP +/* FPGA programming support */ +#define CONFIG_FPGA +#define CONFIG_FPGA_ALTERA +#define CONFIG_FPGA_STRATIX_V + /* * mv-common.h should be defined after CMD configs since it used them * to enable certain macros -- cgit v1.3.1