diff options
author | Alex White <alex.white@oarcorp.com> | 2022-12-18 21:07:11 -0600 |
---|---|---|
committer | Joel Sherrill <joel@rtems.org> | 2023-01-27 14:49:28 -0600 |
commit | 098ad421a16234c81eea3f74173516fc2e07ba70 (patch) | |
tree | e658e220b5cb7d3c43a2e69ec8e20c9a72bf42d5 /bsps | |
parent | bsps: Add Xilinx GQSPI flash helper (diff) | |
download | rtems-098ad421a16234c81eea3f74173516fc2e07ba70.tar.bz2 |
bsps/xilinx-zynqmp: Add JFFS2 GQSPI NOR driver
Diffstat (limited to 'bsps')
-rw-r--r-- | bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h | 1 | ||||
-rw-r--r-- | bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h | 62 | ||||
-rw-r--r-- | bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c | 186 |
3 files changed, 249 insertions, 0 deletions
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h index 3ffb01d1df..2cbe99f863 100644 --- a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h +++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h @@ -53,6 +53,7 @@ extern "C" { /* Interrupts vectors */ #define BSP_TIMER_VIRT_PPI 27 #define BSP_TIMER_PHYS_NS_PPI 30 +#define ZYNQMP_IRQ_QSPI 47 #define ZYNQMP_IRQ_I2C_0 49 #define ZYNQMP_IRQ_I2C_1 50 #define ZYNQMP_IRQ_UART_0 54 diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h new file mode 100644 index 0000000000..ac957bb686 --- /dev/null +++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsAArch64XilinxZynqMP + * + * @brief XilinxZynqMP QSPI JFFS2 flash driver definitions + */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H +#define LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H + +#include "xqspipsu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Mount jffs2 filesystem. + * + * @param[in] mount_dir The directory to mount the filesystem at. + * @param[in] qspipsu_ptr A pointer to an initialized QSPI instance. + * + * @retval 0 Successful operation. Negative number otherwise. + */ +int xilinx_zynqmp_nor_jffs2_initialize( + const char *mount_dir, + XQspiPsu *qspipsu_ptr +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H */ diff --git a/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c new file mode 100644 index 0000000000..f647c19ec1 --- /dev/null +++ b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string.h> + +#include <bsp/irq.h> +#include <bsp/jffs2_xqspipsu.h> +#include <rtems/jffs2.h> +#include <rtems/libio.h> +#include <xqspipsu-flash-helper.h> + +typedef struct { + rtems_jffs2_flash_control super; + XQspiPsu *qspipsu; +} flash_control; + +/* From the N25Q512A datasheet */ +#define BLOCK_SIZE (64UL * 1024UL) +#define FLASH_SIZE (1024UL * BLOCK_SIZE) +#define FLASH_DEVICE_ID 0xbb20 /* Type: 0xbb, Capacity: 0x20 */ + +static flash_control *get_flash_control( rtems_jffs2_flash_control *super ) +{ + return (flash_control *) super; +} + +static int do_read( + rtems_jffs2_flash_control *super, + uint32_t offset, + unsigned char *buffer, + size_t size_of_buffer +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + u8* ReadBuffer = NULL; + + Status = QspiPsu_NOR_Read( + QspiPsuPtr, + offset, + size_of_buffer, + &ReadBuffer + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + /* + * We have to copy since we can't be sure that buffer is properly aligned. + */ + memcpy( buffer, ReadBuffer, size_of_buffer ); + + return 0; +} + +static int do_write( + rtems_jffs2_flash_control *super, + uint32_t offset, + const unsigned char *buffer, + size_t size_of_buffer +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + + Status = QspiPsu_NOR_Write( + QspiPsuPtr, + offset, + size_of_buffer, + (unsigned char *) buffer + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + return 0; +} + +static int do_erase( + rtems_jffs2_flash_control *super, + uint32_t offset +) +{ + int Status; + + flash_control *self = get_flash_control( super ); + XQspiPsu *QspiPsuPtr = self->qspipsu; + + Status = QspiPsu_NOR_Erase( + QspiPsuPtr, + offset, + BLOCK_SIZE + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + return 0; +} + +static void do_destroy( rtems_jffs2_flash_control *super ) +{ + flash_control *self = get_flash_control( super ); + + rtems_interrupt_handler_remove( + ZYNQMP_IRQ_QSPI, + (rtems_interrupt_handler) XQspiPsu_InterruptHandler, + self->qspipsu + ); +} + +static flash_control flash_instance = { + .super = { + .block_size = BLOCK_SIZE, + .flash_size = FLASH_SIZE, + .read = do_read, + .write = do_write, + .erase = do_erase, + .destroy = do_destroy, + .device_identifier = FLASH_DEVICE_ID + } +}; + +static rtems_jffs2_mount_data mount_data = { + .flash_control = &flash_instance.super, + .compressor_control = NULL +}; + +int xilinx_zynqmp_nor_jffs2_initialize( + const char *mount_dir, + XQspiPsu *qspipsu_ptr +) +{ + int rv = 0; + + flash_instance.qspipsu = qspipsu_ptr; + + rv = QspiPsu_NOR_Initialize( + flash_instance.qspipsu, + ZYNQMP_IRQ_QSPI + ); + if ( rv != 0 ) { + return rv; + } + + rv = mount( + NULL, + mount_dir, + RTEMS_FILESYSTEM_TYPE_JFFS2, + RTEMS_FILESYSTEM_READ_WRITE, + &mount_data + ); + if ( rv != 0 ) { + return rv; + } + + return 0; +} |