Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup lpc32xx_nand_mlc
0007  *
0008  * @brief lpc32xx_mlc_erase_block_safe(), lpc32xx_mlc_erase_block_safe_3(), and
0009  * lpc32xx_mlc_zero_block() implementation.
0010  */
0011 
0012 /*
0013  * Copyright (c) 2011 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #include <bsp/nand-mlc.h>
0038 
0039 #include <string.h>
0040 
0041 #include <bsp.h>
0042 
0043 void lpc32xx_mlc_zero_pages(uint32_t page_begin, uint32_t page_end)
0044 {
0045   uint32_t page = 0;
0046 
0047   for (page = page_begin; page < page_end; ++page) {
0048     lpc32xx_mlc_write_page_with_ecc(
0049       page,
0050       lpc32xx_magic_zero_begin,
0051       lpc32xx_magic_zero_begin
0052     );
0053   }
0054 }
0055 
0056 static rtems_status_code is_valid_page(
0057   uint32_t page_begin,
0058   uint32_t page_offset
0059 )
0060 {
0061   rtems_status_code sc = RTEMS_SUCCESSFUL;
0062   uint32_t spare [MLC_LARGE_SPARE_WORD_COUNT];
0063 
0064   memset(spare, 0, MLC_LARGE_SPARE_SIZE);
0065 
0066   sc = lpc32xx_mlc_read_page(
0067     page_begin + page_offset,
0068     lpc32xx_magic_zero_begin,
0069     spare,
0070     NULL
0071   );
0072   if (sc == RTEMS_SUCCESSFUL) {
0073     if (lpc32xx_mlc_is_bad_page(spare)) {
0074       sc = RTEMS_INCORRECT_STATE;
0075     }
0076   }
0077 
0078   return sc;
0079 }
0080 
0081 static rtems_status_code is_valid_block(uint32_t page_begin)
0082 {
0083   rtems_status_code sc = RTEMS_SUCCESSFUL;
0084 
0085   if (lpc32xx_mlc_page_size() == 512 && lpc32xx_mlc_io_width() == 8) {
0086     sc = is_valid_page(page_begin, 0);
0087     if (sc == RTEMS_SUCCESSFUL) {
0088       sc = is_valid_page(page_begin, 1);
0089     }
0090   } else {
0091     sc = RTEMS_NOT_IMPLEMENTED;
0092   }
0093 
0094   return sc;
0095 }
0096 
0097 rtems_status_code lpc32xx_mlc_is_valid_block(uint32_t block_index)
0098 {
0099   uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
0100   uint32_t page_begin = block_index * pages_per_block;
0101 
0102   return is_valid_block(page_begin);
0103 }
0104 
0105 rtems_status_code lpc32xx_mlc_erase_block_safe_3(
0106   uint32_t block_index,
0107   uint32_t page_begin,
0108   uint32_t page_end
0109 )
0110 {
0111   rtems_status_code sc = RTEMS_SUCCESSFUL;
0112 
0113   sc = is_valid_block(page_begin);
0114   if (sc == RTEMS_SUCCESSFUL) {
0115     sc = lpc32xx_mlc_erase_block(block_index);
0116     if (sc == RTEMS_UNSATISFIED) {
0117       lpc32xx_mlc_zero_pages(page_begin, page_end);
0118     }
0119   }
0120 
0121   return sc;
0122 }
0123 
0124 rtems_status_code lpc32xx_mlc_erase_block_safe(uint32_t block_index)
0125 {
0126   uint32_t pages_per_block = lpc32xx_mlc_pages_per_block();
0127   uint32_t page_begin = block_index * pages_per_block;
0128   uint32_t page_end = page_begin + pages_per_block;
0129 
0130   return lpc32xx_mlc_erase_block_safe_3(
0131     block_index,
0132     page_begin,
0133     page_end
0134   );
0135 }