Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:05

0001 /*
0002  * Copyright (C) 2023, 2023 Aaron Nyholm
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
0014  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0016  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0017  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0018  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0019  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0020  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0021  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0022  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0023  * POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #include <bsp/irq.h>
0027 #include <dev/spi/xqspi_flash.h>
0028 #include <dev/spi/xqspipsu.h>
0029 #include <dev/spi/xqspipsu-flash-helper.h>
0030 #include <dev/spi/xqspipsu_flash_config.h>
0031 
0032 #include <stdlib.h>
0033 #include <string.h>
0034 
0035 static uint32_t xqspi_get_jedec_id(rtems_flashdev *flash) {
0036   return QspiPsu_NOR_Get_JEDEC_ID(flash->driver);
0037 }
0038 
0039 static int xqspi_get_flash_type(
0040   rtems_flashdev *flash,
0041   rtems_flashdev_flash_type *type
0042 )
0043 {
0044   *type = RTEMS_FLASHDEV_NOR;
0045   return 0;
0046 }
0047 
0048 static int xqspi_read_wrapper(
0049     rtems_flashdev *flash,
0050     uintptr_t offset,
0051     size_t count,
0052     void *buffer
0053 )
0054 {
0055   XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;
0056   return QspiPsu_NOR_Read(flash_driver, (uint32_t)offset, (uint32_t)count, buffer);
0057 }
0058 
0059 static int xqspi_page_info_by_off(
0060   rtems_flashdev *flash,
0061   off_t search_offset,
0062   off_t *page_offset,
0063   size_t *page_size
0064 )
0065 {
0066   *page_size = QspiPsu_NOR_Get_Page_Size(flash->driver);
0067   *page_offset = search_offset - (search_offset%((off_t)(*page_size)));
0068   return 0;
0069 }
0070 
0071 static int xqspi_page_info_by_index(
0072   rtems_flashdev *flash,
0073   off_t search_index,
0074   off_t *page_offset,
0075   size_t *page_size
0076 )
0077 {
0078   *page_size = QspiPsu_NOR_Get_Page_Size(flash->driver);
0079   *page_offset = *page_size * search_index;
0080   return 0;
0081 }
0082 
0083 static int xqspi_page_count(
0084   rtems_flashdev *flash,
0085   int *page_count
0086 )
0087 {
0088   *page_count = QspiPsu_NOR_Get_Device_Size(flash->driver) /
0089                   QspiPsu_NOR_Get_Page_Size(flash->driver);
0090   return 0;
0091 }
0092 
0093 static int xqspi_write_block_size(
0094   rtems_flashdev *flash,
0095   size_t *write_block_size
0096 )
0097 {
0098   *write_block_size = QspiPsu_NOR_Get_Page_Size(flash->driver);
0099   return 0;
0100 }
0101 
0102 static int xqspi_write_wrapper(
0103   rtems_flashdev *flash,
0104   uintptr_t offset,
0105   size_t count,
0106   const void *buffer
0107 )
0108 {
0109   XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;
0110   return QspiPsu_NOR_Write(flash_driver, (uint32_t)offset, (uint32_t)count,
0111     (void*)buffer);
0112 }
0113 
0114 static int xqspi_erase_wrapper(
0115   rtems_flashdev *flash,
0116   uintptr_t offset,
0117   size_t count
0118 )
0119 {
0120   XQspiPsu *flash_driver = (XQspiPsu*)flash->driver;
0121   return QspiPsu_NOR_Erase(flash_driver, (uint32_t)offset, (uint32_t)count);
0122 }
0123 
0124 rtems_flashdev* xqspi_flash_init(XQspiPsu *xQspiDev)
0125 {
0126   xqspi_flash_region_table *xtable =
0127     calloc(1, sizeof(xqspi_flash_region_table));
0128 
0129   if (xtable == NULL) {
0130     return NULL;
0131   }
0132 
0133   rtems_flashdev_region_table *ftable =
0134     calloc(1, sizeof(rtems_flashdev_region_table));
0135 
0136   if (ftable == NULL) {
0137     free(xtable);
0138     return NULL;
0139   }
0140 
0141   ftable->regions = (rtems_flashdev_region*)xtable;
0142   ftable->max_regions = XQSPI_FLASH_MAX_REGIONS;
0143   ftable->bit_allocator = &(xtable->xqspi_flash_bit_allocator);
0144 
0145   rtems_flashdev *flash =
0146     rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));
0147 
0148   if (flash == NULL) {
0149     free(xtable);
0150     free(ftable);
0151     return NULL;
0152   }
0153 
0154   flash->driver = xQspiDev;
0155   flash->read = &xqspi_read_wrapper;
0156   flash->write = &xqspi_write_wrapper;
0157   flash->erase = &xqspi_erase_wrapper;
0158   flash->jedec_id = &xqspi_get_jedec_id;
0159   flash->flash_type = &xqspi_get_flash_type;
0160   flash->page_info_by_offset = &xqspi_page_info_by_off;
0161   flash->page_info_by_index = &xqspi_page_info_by_index;
0162   flash->page_count = &xqspi_page_count;
0163   flash->write_block_size = &xqspi_write_block_size;
0164   flash->region_table = ftable;
0165 
0166   return flash;
0167 }
0168 
0169 void xqspi_flash_destroy(rtems_flashdev* flash)
0170 {
0171   free(flash->region_table->regions);
0172   free(flash->region_table);
0173   rtems_flashdev_destroy_and_free(flash);
0174 }