Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:39

0001 /*
0002  * Copyright (C) 2024 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/zynq-qspi-flashdev.h>
0028 #include <dev/spi/zynq-qspi-flash.h>
0029 
0030 #include <stdlib.h>
0031 #include <string.h>
0032 
0033 static uint32_t zqspi_get_jedec_id(rtems_flashdev *flash) {
0034   uint32_t jedec = 0;
0035   zqspi_readid(flash->driver, &jedec);
0036   return (jedec);
0037 }
0038 
0039 static int zqspi_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 zqspi_read_wrapper(
0049     rtems_flashdev *flash,
0050     uintptr_t offset,
0051     size_t count,
0052     void *buffer
0053 )
0054 {
0055   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0056   return zqspi_read(flash_driver, (uint32_t)offset, buffer, count);
0057 }
0058 
0059 static int zqspi_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   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0067   *page_size = (size_t)flash_driver->flash_page_size;
0068   *page_offset = search_offset - (search_offset%((off_t)(*page_size)));
0069   return 0;
0070 }
0071 
0072 static int zqspi_page_info_by_index(
0073   rtems_flashdev *flash,
0074   off_t search_index,
0075   off_t *page_offset,
0076   size_t *page_size
0077 )
0078 {
0079   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0080   *page_size = (size_t)flash_driver->flash_page_size;
0081   *page_offset = *page_size * search_index;
0082   return 0;
0083 }
0084 
0085 static int zqspi_page_count(
0086   rtems_flashdev *flash,
0087   int *page_count
0088 )
0089 {
0090   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0091   *page_count = flash_driver->flash_size /
0092                   flash_driver->flash_page_size;
0093   return 0;
0094 }
0095 
0096 static int zqspi_write_block_size(
0097   rtems_flashdev *flash,
0098   size_t *write_block_size
0099 )
0100 {
0101   *write_block_size = 1u;
0102   return 0;
0103 }
0104 
0105 static int zqspi_write_wrapper(
0106   rtems_flashdev *flash,
0107   uintptr_t offset,
0108   size_t count,
0109   const void *buffer
0110 )
0111 {
0112   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0113   return zqspi_write(flash_driver, (uint32_t)offset, buffer, count);
0114 }
0115 
0116 static int zqspi_erase_wrapper(
0117   rtems_flashdev *flash,
0118   uintptr_t offset,
0119   size_t count
0120 )
0121 {
0122   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0123   return zqspi_erase(flash_driver, (uint32_t)offset, count);
0124 }
0125 
0126 static int zqspi_sector_info_by_off(
0127   rtems_flashdev *flash,
0128   off_t search_offset,
0129   off_t *sector_offset,
0130   size_t *sector_size
0131 )
0132 {
0133   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0134   *sector_size = (size_t)flash_driver->flash_erase_sector_size;
0135   *sector_offset = search_offset - (search_offset%((off_t)(*sector_size)));
0136   return 0;
0137 }
0138 
0139 static int zqspi_sector_count(
0140   rtems_flashdev *flash,
0141   int *sector_count
0142 )
0143 {
0144   zqspiflash *flash_driver = (zqspiflash*)flash->driver;
0145   *sector_count = flash_driver->flash_size /
0146                   flash_driver->flash_erase_sector_size;
0147   return 0;
0148 }
0149 
0150 rtems_flashdev* zqspi_flashdev_init(zqspiflash *bmdriver)
0151 {
0152   zqspi_flash_region_table *xtable =
0153     calloc(1, sizeof(zqspi_flash_region_table));
0154 
0155   if (xtable == NULL) {
0156     return NULL;
0157   }
0158 
0159   rtems_flashdev_region_table *ftable =
0160     calloc(1, sizeof(rtems_flashdev_region_table));
0161 
0162   if (ftable == NULL) {
0163     free(xtable);
0164     return NULL;
0165   }
0166 
0167   ftable->regions = (rtems_flashdev_region*)xtable;
0168   ftable->max_regions = ZQSPI_FLASH_MAX_REGIONS;
0169   ftable->bit_allocator = &(xtable->zqspi_flash_bit_allocator);
0170 
0171   rtems_flashdev *flash =
0172     rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));
0173 
0174   if (flash == NULL) {
0175     free(xtable);
0176     free(ftable);
0177     return NULL;
0178   }
0179 
0180   flash->driver = bmdriver;
0181   flash->read = &zqspi_read_wrapper;
0182   flash->write = &zqspi_write_wrapper;
0183   flash->erase = &zqspi_erase_wrapper;
0184   flash->jedec_id = &zqspi_get_jedec_id;
0185   flash->flash_type = &zqspi_get_flash_type;
0186   flash->page_info_by_offset = &zqspi_page_info_by_off;
0187   flash->page_info_by_index = &zqspi_page_info_by_index;
0188   flash->page_count = &zqspi_page_count;
0189   flash->write_block_size = &zqspi_write_block_size;
0190   flash->sector_info_by_offset = &zqspi_sector_info_by_off;
0191   flash->sector_count = &zqspi_sector_count;
0192   flash->region_table = ftable;
0193 
0194   return flash;
0195 }
0196 
0197 void zqspi_flashdev_destroy(rtems_flashdev* flash)
0198 {
0199   free(flash->region_table->regions);
0200   free(flash->region_table);
0201   rtems_flashdev_destroy_and_free(flash);
0202 }