From: Aaron Nyholm <aaron.nyh...@southerninnovation.com> --- .../dev/spi/versal_xqspi_flash.c | 296 ++++++++++++++++++ bsps/aarch64/xilinx-versal/include/bsp/irq.h | 1 + .../include/dev/spi/versal_xqspi_flash.h | 49 +++ bsps/include/dev/spi/xqspipsu-flash-helper.h | 24 ++ bsps/shared/dev/spi/xqspipsu-flash-helper.c | 16 + spec/build/bsps/aarch64/xilinx-versal/grp.yml | 2 + .../aarch64/xilinx-versal/objxqspiflash.yml | 24 ++ 7 files changed, 412 insertions(+) create mode 100644 bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c create mode 100644 bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h create mode 100644 spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml
diff --git a/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c b/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c new file mode 100644 index 0000000000..7771af9dcd --- /dev/null +++ b/bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2023, 2023 Aaron Nyholm + * + * 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 <bsp/irq.h> +#include <dev/spi/versal_xqspi_flash.h> +#include <dev/spi/xqspipsu.h> +#include <dev/spi/xqspipsu-flash-helper.h> +#include <dev/spi/xqspipsu_flash_config.h> + +#include <stdlib.h> +#include <string.h> + + +uint32_t xqspi_get_jedec_id(rtems_flashdev *flash); + +int xqspi_get_flash_type( + rtems_flashdev *flash, + rtems_flashdev_flash_type *type +); + +int xqspi_page_info_by_off( + rtems_flashdev *flash, + off_t search_offset, + off_t *page_offset, + size_t *page_size +); + +int xqspi_page_info_by_index( + rtems_flashdev *flash, + off_t search_index, + off_t *page_offset, + size_t *page_size +); + +int xqspi_page_count( + rtems_flashdev *flash, + int *page_count +); + +int xqspi_write_block_size( + rtems_flashdev *flash, + size_t *write_block_size +); + +int xqspi_read_wrapper(rtems_flashdev *flash, + uintptr_t offset, + size_t count, + void *buffer +); + +int xqspi_write_wrapper( + rtems_flashdev *flash, + uintptr_t offset, + size_t count, + const void *buffer +); + +int xqspi_erase_wrapper( + rtems_flashdev *flash, + uintptr_t offset, + size_t count +); + +uint32_t xqspi_get_jedec_id(rtems_flashdev *flash) { + return QspiPsu_NOR_Get_JEDEC_ID(flash->driver); +} + +int xqspi_get_flash_type( + rtems_flashdev *flash, + rtems_flashdev_flash_type *type +) +{ + *type = RTEMS_FLASHDEV_NOR; + return 0; +} + +int xqspi_read_wrapper( + rtems_flashdev *flash, + uintptr_t offset, + size_t count, + void *buffer +) +{ + XQspiPsu *flash_driver = (XQspiPsu*)flash->driver; + uint8_t *tmp_buffer; + int status; + int startAlign = 0; + + /* Align offset to two byte boundary */ + if (offset%2) { + startAlign = 1; + offset = offset - 1; + count = count + 1; + } + + while (count > MAX_READ_SIZE) { + /* Read block and copy to buffer */ + status = QspiPsu_NOR_Read(flash_driver, (uint32_t)offset, MAX_READ_SIZE, &tmp_buffer); + + if (status == 0) { + memcpy(buffer, tmp_buffer + startAlign, MAX_READ_SIZE - startAlign); + /* Update count, offset and buffer pointer */ + count = count - MAX_READ_SIZE; + buffer = buffer + MAX_READ_SIZE - startAlign; + offset = offset + MAX_READ_SIZE; + /* Clear startAlign once first block read */ + if (startAlign) { + startAlign = 0; + } + } else { + return status; + } + } + + status = QspiPsu_NOR_Read(flash_driver, (uint32_t)offset, (uint32_t)count, &tmp_buffer); + + if (status == 0) { + memcpy(buffer, tmp_buffer + startAlign, count); + } + return status; +} + +int xqspi_page_info_by_off( + rtems_flashdev *flash, + off_t search_offset, + off_t *page_offset, + size_t *page_size +) +{ + *page_size = QspiPsu_NOR_Get_Sector_Size(flash->driver); + *page_offset = search_offset - (search_offset%((off_t)(*page_size))); + return 0; +} + +int xqspi_page_info_by_index( + rtems_flashdev *flash, + off_t search_index, + off_t *page_offset, + size_t *page_size +) +{ + *page_size = QspiPsu_NOR_Get_Page_Size(flash->driver); + *page_offset = *page_size * search_index; + return 0; +} + +int xqspi_page_count( + rtems_flashdev *flash, + int *page_count +) +{ + *page_count = QspiPsu_NOR_Get_Device_Size(flash->driver) / + QspiPsu_NOR_Get_Page_Size(flash->driver); + return 0; +} + +int xqspi_write_block_size( + rtems_flashdev *flash, + size_t *write_block_size +) +{ + *write_block_size = QspiPsu_NOR_Get_Page_Size(flash->driver); + return 0; +} + +int xqspi_write_wrapper( + rtems_flashdev *flash, + uintptr_t offset, + size_t count, + const void *buffer +) +{ + XQspiPsu *flash_driver = (XQspiPsu*)flash->driver; + return QspiPsu_NOR_Write(flash_driver, (uint32_t)offset, (uint32_t)count, (void*)buffer); +} + +int xqspi_erase_wrapper( + rtems_flashdev *flash, + uintptr_t offset, + size_t count +) +{ + XQspiPsu *flash_driver = (XQspiPsu*)flash->driver; + return QspiPsu_NOR_Erase(flash_driver, (uint32_t)offset, (uint32_t)count); +} + +rtems_flashdev* xqspi_flash_init(void) +{ + int status; + XQspiPsu *xQspiDev; + XQspiPsu_Config *xQspiDev_Config; + + xQspiDev = calloc(1, sizeof(XQspiPsu)); + if (xQspiDev == NULL) { + return NULL; + } + xQspiDev_Config = calloc(1, sizeof(XQspiPsu_Config)); + if (xQspiDev_Config == NULL) { + free(xQspiDev); + return NULL; + } + + xQspiDev_Config->DeviceId = 0; + xQspiDev_Config->BaseAddress = XQSPIPS_BASEADDR; + xQspiDev_Config->InputClockHz = VERSAL_QSPI_INPUT_CLOCK_HZ; + xQspiDev_Config->ConnectionMode = XQSPIPSU_CONNECTION_MODE_PARALLEL; + xQspiDev_Config->BusWidth = 2; + xQspiDev_Config->IsCacheCoherent = 0; + + status = XQspiPsu_CfgInitialize(xQspiDev, xQspiDev_Config, XQSPIPS_BASEADDR); + + if (status != 0) { + free(xQspiDev); + free(xQspiDev_Config); + return NULL; + } + + versal_xqspi_region_table *xtable = + calloc(1, sizeof(versal_xqspi_region_table)); + + if (xtable == NULL) { + free(xQspiDev); + free(xQspiDev_Config); + return NULL; + } + + rtems_flashdev_region_table *ftable = + calloc(1, sizeof(rtems_flashdev_region_table)); + + if (ftable == NULL) { + free(ftable); + free(xQspiDev); + free(xQspiDev_Config); + return NULL; + } + + ftable->regions = (rtems_flashdev_region*)(&(xtable->versal_xqspi_regions)); + ftable->max_regions = VERSAL_XQSPI_MAX_REGIONS; + ftable->bit_allocator = &(xtable->versal_xqspi_bit_allocator); + + status = QspiPsu_NOR_Initialize( + xQspiDev, + VERSAL_IRQ_QSPI + ); + + if (status != 0) { + free(xQspiDev); + free(xQspiDev_Config); + return NULL; + } + + rtems_flashdev *flash = rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev)); + + if (flash == NULL) { + free(xQspiDev); + free(xQspiDev_Config); + return NULL; + } + + flash->driver = xQspiDev; + flash->read = &xqspi_read_wrapper; + flash->write = &xqspi_write_wrapper; + flash->erase = &xqspi_erase_wrapper; + flash->jedec_id = &xqspi_get_jedec_id; + flash->flash_type = &xqspi_get_flash_type; + flash->page_info_by_offset = &xqspi_page_info_by_off; + flash->page_info_by_index = &xqspi_page_info_by_index; + flash->page_count = &xqspi_page_count; + flash->write_block_size = &xqspi_write_block_size; + flash->region_table = ftable; + + return flash; + +} diff --git a/bsps/aarch64/xilinx-versal/include/bsp/irq.h b/bsps/aarch64/xilinx-versal/include/bsp/irq.h index b34bdfd345..6f4d387e8f 100644 --- a/bsps/aarch64/xilinx-versal/include/bsp/irq.h +++ b/bsps/aarch64/xilinx-versal/include/bsp/irq.h @@ -61,6 +61,7 @@ extern "C" { #define VERSAL_IRQ_ETHERNET_0_WAKEUP 89 #define VERSAL_IRQ_ETHERNET_1 90 #define VERSAL_IRQ_ETHERNET_1_WAKEUP 91 +#define VERSAL_IRQ_QSPI 157 /** @} */ diff --git a/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h b/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h new file mode 100644 index 0000000000..fe0ffd3e71 --- /dev/null +++ b/bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2023, 2023 Aaron Nyholm + * + * 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_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H +#define LIBBSP_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H + +#include <dev/flash/flashdev.h> + +#define VERSAL_XQSPI_MAX_REGIONS 32 +#define VERSAL_QSPI_INPUT_CLOCK_HZ 295833038 +#define MAX_READ_SIZE 0x8000 + +/* + * Initalize a qspi_flash device using Xilinx's qspi flash + * driver. Device still needs to be registered using + * qspi_flash_register in qspi_flash.c. +*/ +rtems_flashdev* xqspi_flash_init(void); + +typedef struct versal_xqspi_region_table { + rtems_flashdev_region versal_xqspi_regions[VERSAL_XQSPI_MAX_REGIONS]; + uint32_t versal_xqspi_bit_allocator; +} versal_xqspi_region_table; + +#endif /* LIBBSP_AARCH64_XILINX_VERSAL_XQSPI_FLASH_H */ diff --git a/bsps/include/dev/spi/xqspipsu-flash-helper.h b/bsps/include/dev/spi/xqspipsu-flash-helper.h index 5e4233e64e..69660d28f7 100644 --- a/bsps/include/dev/spi/xqspipsu-flash-helper.h +++ b/bsps/include/dev/spi/xqspipsu-flash-helper.h @@ -155,3 +155,27 @@ u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr); * ******************************************************************************/ u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr); + +/*****************************************************************************/ +/** + * + * This function returns the page size of attached flash parts. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * + * @return The page size of attached flash in bytes. + * + ******************************************************************************/ +u32 QspiPsu_NOR_Get_Page_Size(XQspiPsu *QspiPsuPtr); + +/*****************************************************************************/ +/** + * + * This function returns the JEDEC ID of attached flash parts. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * + * @return The JEDEC ID of attached flash in bytes. + * + ******************************************************************************/ +u32 QspiPsu_NOR_Get_JEDEC_ID(XQspiPsu *QspiPsuPtr); diff --git a/bsps/shared/dev/spi/xqspipsu-flash-helper.c b/bsps/shared/dev/spi/xqspipsu-flash-helper.c index c9d8273b87..1795c9756b 100644 --- a/bsps/shared/dev/spi/xqspipsu-flash-helper.c +++ b/bsps/shared/dev/spi/xqspipsu-flash-helper.c @@ -2277,3 +2277,19 @@ u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr) } return Flash_Config_Table[FCTIndex].FlashDeviceSize; } + +u32 QspiPsu_NOR_Get_Page_Size(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) { + return Flash_Config_Table[FCTIndex].PageSize * 2; + } + return Flash_Config_Table[FCTIndex].PageSize; +} + +u32 QspiPsu_NOR_Get_JEDEC_ID(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) { + return Flash_Config_Table[FCTIndex].jedec_id * 2; + } + return Flash_Config_Table[FCTIndex].jedec_id; +} diff --git a/spec/build/bsps/aarch64/xilinx-versal/grp.yml b/spec/build/bsps/aarch64/xilinx-versal/grp.yml index badfa07fcc..098a8481db 100644 --- a/spec/build/bsps/aarch64/xilinx-versal/grp.yml +++ b/spec/build/bsps/aarch64/xilinx-versal/grp.yml @@ -24,6 +24,8 @@ links: uid: abi - role: build-dependency uid: obj +- role: build-dependency + uid: objxqspiflash - role: build-dependency uid: optconirq - role: build-dependency diff --git a/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml b/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml new file mode 100644 index 0000000000..6d84bfa8cd --- /dev/null +++ b/spec/build/bsps/aarch64/xilinx-versal/objxqspiflash.yml @@ -0,0 +1,24 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: objects +cflags: [] +copyrights: +- Copyright (C) 2022 On-Line Applications Research (OAR) +cppflags: [] +cxxflags: [] +enabled-by: true +includes: +- bsps/include/dev/spi/ +- bsps/include/xil/ +- bsps/include/xil/${XIL_SUPPORT_PATH}/ +install: +- destination: ${BSP_INCLUDEDIR}/bsp + source: + - bsps/aarch64/xilinx-versal/include/dev/spi/versal_xqspi_flash.h +links: +- role: build-dependency + uid: ../../objxilinxsupport +- role: build-dependency + uid: ../../objqspipsu +source: + - bsps/aarch64/xilinx-versal/dev/spi/versal_xqspi_flash.c +type: build -- 2.25.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel