boards: arty: add support for daplink qspi mux
The ARM Cortex-M1/M3 DesignStart FPGA reference designs support booting from an off-board, memory-mapped QSPI NOR flash device. The V2C DAPlink shield from ARM Ltd. provides support for this feature. If the board/shield is not configured for booting from the QSPI NOR device, that same device is available as a regular QSPI NOR flash device. The presense of a shield configured for QSPI NOR flash boot is indicated through an IRQ line used as a level-detect, non-interrupt signal. Introduce a board specific devicetree binding for the DAPLink QSPI MUX and provide a board specific API accessing it. Automatically set the QSPI MUX to to provide regular QSPI NOR flash access if the board/shield is not configured for memory-mapped QSPI NOR flash boot. Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
This commit is contained in:
parent
217560d8e1
commit
4c57f3400a
7 changed files with 190 additions and 0 deletions
|
@ -1,5 +1,8 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
zephyr_library()
|
||||||
|
zephyr_library_sources(board.c)
|
||||||
|
|
||||||
if((CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) AND (CONFIG_BUILD_OUTPUT_BIN))
|
if((CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) AND (CONFIG_BUILD_OUTPUT_BIN))
|
||||||
# Generate zephyr.mem verilog memory hex dump file for initialising ITCM in
|
# Generate zephyr.mem verilog memory hex dump file for initialising ITCM in
|
||||||
# Xilinx Vivado.
|
# Xilinx Vivado.
|
||||||
|
|
13
boards/arm/arty/Kconfig
Normal file
13
boards/arm/arty/Kconfig
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Digilent Arty board configuration
|
||||||
|
|
||||||
|
# Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config BOARD_INIT_PRIORITY
|
||||||
|
int "Board initialization priority"
|
||||||
|
default 50
|
||||||
|
depends on BOARD_ARTY_A7_ARM_DESIGNSTART_M1 || BOARD_ARTY_A7_ARM_DESIGNSTART_M3
|
||||||
|
depends on "$(dt_nodelabel_enabled,daplink_qspi_mux)"
|
||||||
|
help
|
||||||
|
Board initialization priority. The board initialization must take
|
||||||
|
place after the GPIO driver is initialized.
|
|
@ -25,6 +25,9 @@ config UART_XLNX_UARTLITE
|
||||||
|
|
||||||
endif # SERIAL
|
endif # SERIAL
|
||||||
|
|
||||||
|
config GPIO
|
||||||
|
default y if "$(dt_nodelabel_enabled,daplink_qspi_mux)"
|
||||||
|
|
||||||
if GPIO
|
if GPIO
|
||||||
|
|
||||||
config GPIO_XLNX_AXI
|
config GPIO_XLNX_AXI
|
||||||
|
|
86
boards/arm/arty/board.c
Normal file
86
boards/arm/arty/board.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch/arm/aarch32/cortex_m/cmsis.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <devicetree.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(board, CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#define DAPLINK_QSPI_MUX_NODE DT_NODELABEL(daplink_qspi_mux)
|
||||||
|
|
||||||
|
#if DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay)
|
||||||
|
int board_daplink_qspi_mux_select(enum board_daplink_qspi_mux_mode mode)
|
||||||
|
{
|
||||||
|
const struct device *gpio;
|
||||||
|
gpio_flags_t flags;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case BOARD_DAPLINK_QSPI_MUX_MODE_XIP:
|
||||||
|
flags = GPIO_OUTPUT_LOW;
|
||||||
|
break;
|
||||||
|
case BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL:
|
||||||
|
flags = GPIO_OUTPUT_HIGH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
__ASSERT(0, "invalid mode");
|
||||||
|
return -EINVAL;
|
||||||
|
};
|
||||||
|
|
||||||
|
gpio = device_get_binding(DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE,
|
||||||
|
mux_gpios));
|
||||||
|
if (!gpio) {
|
||||||
|
LOG_ERR("DAPLink QSPI MUX GPIO device '%s' not found",
|
||||||
|
DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE, mux_gpios));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gpio_config(gpio, DT_GPIO_PIN(DAPLINK_QSPI_MUX_NODE, mux_gpios),
|
||||||
|
DT_GPIO_FLAGS(DAPLINK_QSPI_MUX_NODE, mux_gpios) |
|
||||||
|
flags);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("failed to configure DAPLink QSPI MUX GPIO (err %d)",
|
||||||
|
err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool board_daplink_is_fitted(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The DAPLINK_fitted_n signal is routed to an IRQ line. It is used as a
|
||||||
|
* level-detect non-interrupt signal to determine if the DAPLink shield
|
||||||
|
* is fitted.
|
||||||
|
*/
|
||||||
|
return !NVIC_GetPendingIRQ(DT_IRQN(DAPLINK_QSPI_MUX_NODE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int board_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Automatically select normal mode unless the DAPLink shield is fitted
|
||||||
|
* in which case the CPU will have the off-board QSPI NOR flash
|
||||||
|
* memory-mapped at 0x0.
|
||||||
|
*/
|
||||||
|
if (!board_daplink_is_fitted()) {
|
||||||
|
board_daplink_qspi_mux_select(
|
||||||
|
BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(board_init, POST_KERNEL, CONFIG_BOARD_INIT_PRIORITY);
|
||||||
|
#endif /* DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay) */
|
40
boards/arm/arty/board.h
Normal file
40
boards/arm/arty/board.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INC_BOARD_H
|
||||||
|
#define __INC_BOARD_H
|
||||||
|
|
||||||
|
enum board_daplink_qspi_mux_mode {
|
||||||
|
/* eXecute-In-Place mode */
|
||||||
|
BOARD_DAPLINK_QSPI_MUX_MODE_XIP,
|
||||||
|
/* Normal mode */
|
||||||
|
BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Select the mode of the DAPlink QSPI multiplexer.
|
||||||
|
*
|
||||||
|
* Note: The multiplexer mode must not be changed while executing code from the
|
||||||
|
* off-board QSPI flash in XIP mode.
|
||||||
|
*
|
||||||
|
* @param mode The multiplexer mode to be selected.
|
||||||
|
*
|
||||||
|
* @retval 0 If successful, negative errno otherwise.
|
||||||
|
*/
|
||||||
|
int board_daplink_qspi_mux_select(enum board_daplink_qspi_mux_mode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determine if the DAPlink shield is fitted.
|
||||||
|
*
|
||||||
|
* Determine if the DAPlink shield is fitted based on the state of the
|
||||||
|
* DAPLINK_fitted_n signal.
|
||||||
|
*
|
||||||
|
* @retval true If the DAPlink shield is fitted.
|
||||||
|
* @retval false If the DAPlink shield is not fitted.
|
||||||
|
*/
|
||||||
|
bool board_daplink_is_fitted(void);
|
||||||
|
|
||||||
|
#endif /* __INC_BOARD_H */
|
|
@ -135,7 +135,31 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
daplink_qspi_mux: daplink_qspi_mux {
|
||||||
|
compatible = "arm,daplink-qspi-mux";
|
||||||
|
status = "disabled";
|
||||||
|
interrupt-parent = <&nvic>;
|
||||||
|
interrupts = <7 0>;
|
||||||
|
mux-gpios = <&daplink_gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
soc {
|
soc {
|
||||||
|
daplink_gpio0: gpio@40010000 {
|
||||||
|
compatible = "xlnx,xps-gpio-1.00.a";
|
||||||
|
status = "disabled";
|
||||||
|
reg = <0x40010000 0x10000>;
|
||||||
|
label = "DAPLINK_GPIO_0";
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
|
||||||
|
xlnx,all-inputs = <0x0>;
|
||||||
|
xlnx,all-outputs = <0x0>;
|
||||||
|
xlnx,dout-default = <0x0>;
|
||||||
|
xlnx,gpio-width = <0x20>;
|
||||||
|
xlnx,is-dual = <0x0>;
|
||||||
|
xlnx,tri-default = <0xffffffff>;
|
||||||
|
};
|
||||||
|
|
||||||
daplink_quad_spi0: spi@40020000 {
|
daplink_quad_spi0: spi@40020000 {
|
||||||
compatible = "xlnx,xps-spi-2.00.a";
|
compatible = "xlnx,xps-spi-2.00.a";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
|
21
boards/arm/arty/dts/bindings/arm,daplink-qspi-mux.yaml
Normal file
21
boards/arm/arty/dts/bindings/arm,daplink-qspi-mux.yaml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: ARM DesignStart FPGA DAPLink QSPI bus multiplexer
|
||||||
|
|
||||||
|
compatible: "arm,daplink-qspi-mux"
|
||||||
|
|
||||||
|
include: base.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
interrupts:
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
IRQ line connected to the level-detect non-interrupt DAPLink shield
|
||||||
|
fitted signal
|
||||||
|
|
||||||
|
mux-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
GPIO for controlling the DAPLink QSPI bus multiplexer
|
Loading…
Add table
Add a link
Reference in a new issue