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
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) */
|
Loading…
Add table
Add a link
Reference in a new issue