1 /*
2 * Copyright 2017-2020, 2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdint.h>
8 #include <string.h>
9
10 #include "mflash_drv.h"
11 #include "fsl_flash.h"
12 #include "fsl_cache.h"
13 #include "fsl_flexspi_nor_flash.h"
14 #include "pin_mux.h"
15
16 #define FLASH_BASE_ADDR 0x80000000UL
17
18 #if FLASH_USE_CUSTOM_FCB
19 /* fcb for w45q64 */
20 const uint8_t CUSTOM_FCB[] = {
21 0x46, 0x43, 0x46, 0x42, 0x00, 0x04, 0x01, 0x56, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x04, 0x18, 0x0a, 0x06,
28 0x32, 0x04, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
32 0x04, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x04, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x18, 0x08, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
45 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
48
49 #endif
50
51 static flexspi_nor_config_t flashConfig;
52
53 /* API - initialize 'mflash' */
mflash_drv_init(void)54 int32_t mflash_drv_init(void)
55 {
56 status_t result;
57
58 #if FLASH_USE_CUSTOM_FCB
59 memcpy(&flashConfig, CUSTOM_FCB, sizeof(flexspi_nor_config_t));
60 #else
61 serial_nor_config_option_t option;
62 option.option0.U = 0xc0000001U;
63 option.option1.U = 0x00000000;
64
65 result = FLEXSPI_NorFlash_GetConfig(0, &flashConfig, &option);
66 if (result != kStatus_Success)
67 {
68 return result;
69 }
70 #endif
71
72 result = FLEXSPI_NorFlash_Init(0, &flashConfig);
73 if (result != kStatus_Success)
74 {
75 return result;
76 }
77
78 return result;
79 }
80
81 /* API - Erase single sector */
mflash_drv_sector_erase(uint32_t sector_addr)82 int32_t mflash_drv_sector_erase(uint32_t sector_addr)
83 {
84 status_t status;
85 uint32_t primask = __get_PRIMASK();
86
87 if (0 == mflash_drv_is_sector_aligned(sector_addr))
88 return kStatus_InvalidArgument;
89
90 __disable_irq();
91
92 status = FLEXSPI_NorFlash_Erase(0, (flexspi_nor_config_t *)&flashConfig, sector_addr,
93 flashConfig.sectorSize);
94
95 DCACHE_InvalidateByRange(MFLASH_BASE_ADDRESS + sector_addr, MFLASH_SECTOR_SIZE);
96
97
98 if (primask == 0U)
99 {
100 __enable_irq();
101 }
102
103 /* Flush pipeline to allow pending interrupts take place
104 * before starting next loop */
105 __ISB();
106
107 return status;
108 }
109
110 /* API - Page program */
mflash_drv_page_program(uint32_t page_addr,uint32_t * data)111 int32_t mflash_drv_page_program(uint32_t page_addr, uint32_t *data)
112 {
113 status_t status;
114 uint32_t primask = __get_PRIMASK();
115
116 if (0 == mflash_drv_is_page_aligned(page_addr))
117 return kStatus_InvalidArgument;
118
119 __disable_irq();
120
121 status = FLEXSPI_NorFlash_ProgramPage(0, &flashConfig, page_addr, (uint32_t *)data);
122
123 DCACHE_InvalidateByRange(MFLASH_BASE_ADDRESS + page_addr, MFLASH_PAGE_SIZE);
124
125
126 if (primask == 0)
127 {
128 __enable_irq();
129 }
130
131 /* Flush pipeline to allow pending interrupts take place
132 * before starting next loop */
133 __ISB();
134
135 return status;
136 }
137
138 /* API - Read data */
mflash_drv_read(uint32_t addr,uint32_t * buffer,uint32_t len)139 int32_t mflash_drv_read(uint32_t addr, uint32_t *buffer, uint32_t len)
140 {
141 memcpy(buffer, (void *)(addr + MFLASH_BASE_ADDRESS), len);
142
143 return kStatus_Success;
144 }
145
146 /* API - Get pointer to FLASH region */
mflash_drv_phys2log(uint32_t addr,uint32_t len)147 void *mflash_drv_phys2log(uint32_t addr, uint32_t len)
148 {
149 return (void *)(addr + MFLASH_BASE_ADDRESS);
150 }
151
152 /* API - Get pointer to FLASH region */
mflash_drv_log2phys(void * ptr,uint32_t len)153 uint32_t mflash_drv_log2phys(void *ptr, uint32_t len)
154 {
155 if ((uint32_t)ptr < MFLASH_BASE_ADDRESS)
156 return kStatus_InvalidArgument;
157
158 return ((uint32_t)ptr - MFLASH_BASE_ADDRESS);
159 }
160