1 /*
2  *  SPDX-License-Identifier: BSD-3-Clause
3  *  SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4  *
5  */
6 
7 #ifndef __DRIVER_FLASH_RPI_H__
8 #define __DRIVER_FLASH_RPI_H__
9 
10 #include "Driver_Flash.h"
11 #include "hardware/flash.h"
12 #include <string.h>
13 
14 #ifndef ARG_UNUSED
15 #define ARG_UNUSED(arg)  ((void)arg)
16 #endif
17 
18 /* Driver version */
19 #define ARM_FLASH_DRV_VERSION   ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
20 
21 static const ARM_DRIVER_VERSION DriverVersion = {
22     ARM_FLASH_API_VERSION,  /* Defined in the CMSIS Flash Driver header file */
23     ARM_FLASH_DRV_VERSION
24 };
25 
26 /**
27  * Data width values for ARM_FLASH_CAPABILITIES::data_width
28  * \ref ARM_FLASH_CAPABILITIES
29  */
30  enum {
31     DATA_WIDTH_8BIT   = 0u,
32     DATA_WIDTH_16BIT,
33     DATA_WIDTH_32BIT,
34     DATA_WIDTH_ENUM_SIZE
35 };
36 
37 /* Flash Status */
38 static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
39 
40 /**
41  * \brief Flash driver capability macro definitions \ref ARM_FLASH_CAPABILITIES
42  */
43 /* Flash Ready event generation capability values */
44 #define EVENT_READY_NOT_AVAILABLE   (0u)
45 #define EVENT_READY_AVAILABLE       (1u)
46 
47 /* Chip erase capability values */
48 #define CHIP_ERASE_NOT_SUPPORTED    (0u)
49 #define CHIP_ERASE_SUPPORTED        (1u)
50 
ARM_Flash_GetVersion(void)51 static inline ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
52 {
53     return DriverVersion;
54 }
55 
56 /* Driver Capabilities */
57 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
58     EVENT_READY_NOT_AVAILABLE,
59     DATA_WIDTH_8BIT,
60     CHIP_ERASE_NOT_SUPPORTED
61 };
62 
63 /*
64  * ARM FLASH device structure
65  */
66 typedef struct rp2350_flash_dev_t{
67     ARM_FLASH_INFO* data;               /* FLASH data */
68     uint32_t base;                      /* Flash base address, used for flash
69                                            reads */
70     uint32_t size;                      /* Flash size */
71     void (*save_mpu_state)(struct rp2350_flash_dev_t* dev);
72                                         /*!< Function to save MPU settings */
73     void (*restore_mpu_state)(void);
74                                         /*!< Function to restore MPU settings */
75 } rp2350_flash_dev_t;
76 
77 /* Driver Capabilities */
78 static const ARM_FLASH_CAPABILITIES PicoDriverCapabilities = {
79     0, /* event_ready */
80     0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
81     0, /* erase_chip */
82     0, /* reserved */
83 };
84 
Pico_Driver_GetCapabilities(void)85 static inline ARM_FLASH_CAPABILITIES Pico_Driver_GetCapabilities(void)
86 {
87     return PicoDriverCapabilities;
88 }
89 
ARM_Flash_Uninitialize(void)90 static inline int32_t ARM_Flash_Uninitialize(void)
91 {
92     /* Nothing to be done */
93     return ARM_DRIVER_OK;
94 }
95 
ARM_Flash_PowerControl(ARM_POWER_STATE state)96 static inline int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
97 {
98     switch (state) {
99     case ARM_POWER_FULL:
100         /* Nothing to be done */
101         return ARM_DRIVER_OK;
102         break;
103 
104     case ARM_POWER_OFF:
105     case ARM_POWER_LOW:
106     default:
107         return ARM_DRIVER_ERROR_UNSUPPORTED;
108     }
109 }
110 
ARM_Flash_GetStatus(void)111 static inline ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
112 {
113     return FlashStatus;
114 }
115 
116 /*
117  * \brief Macro for Pico Flash Driver
118  *
119  * \param[out] FLASH_DRIVER_NAME  Resulting Driver name
120  */
121 #define RPI_RP2350_FLASH(FLASH_DEV, FLASH_DRIVER_NAME)                          \
122                                                                               \
123 static int32_t FLASH_DRIVER_NAME##_Initialize(                                \
124                                             ARM_Flash_SignalEvent_t cb_event) \
125 {                                                                             \
126     ARG_UNUSED(cb_event);                                                     \
127     return ARM_DRIVER_OK;                                                     \
128 }                                                                             \
129                                                                               \
130 static int32_t FLASH_DRIVER_NAME##_ReadData(uint32_t addr,                    \
131                                             void *data,                       \
132                                             uint32_t cnt)                     \
133 {                                                                             \
134     if ((addr+cnt) >= FLASH_DEV.size) {                                       \
135         return ARM_DRIVER_ERROR_PARAMETER;                                    \
136     }                                                                         \
137                                                                               \
138     memcpy(data, (void *)(addr + FLASH_DEV.base), cnt);                       \
139                                                                               \
140     return ARM_DRIVER_OK;                                                     \
141 }                                                                             \
142                                                                               \
143 static int32_t FLASH_DRIVER_NAME##_ProgramData(uint32_t addr,                 \
144                                                const void *data,              \
145                                                uint32_t cnt)                  \
146 {                                                                             \
147     if ((addr+cnt) >= FLASH_DEV.size) {                                       \
148         return ARM_DRIVER_ERROR_PARAMETER;                                    \
149     }                                                                         \
150                                                                               \
151     if ((cnt < FLASH_DEV.data->program_unit) ||                               \
152         (cnt % FLASH_DEV.data->program_unit) ||                               \
153         (addr % FLASH_DEV.data->page_size)) {                                 \
154         return ARM_DRIVER_ERROR_PARAMETER;                                    \
155     }                                                                         \
156                                                                               \
157     FLASH_DEV.save_mpu_state(&FLASH_DEV);                                     \
158                                                                               \
159     flash_range_program(addr, data, cnt);                                     \
160                                                                               \
161     FLASH_DEV.restore_mpu_state();                                            \
162                                                                               \
163     return ARM_DRIVER_OK;                                                     \
164 }                                                                             \
165                                                                               \
166 static int32_t FLASH_DRIVER_NAME##_EraseSector(uint32_t addr)                 \
167 {                                                                             \
168     if (addr >= FLASH_DEV.size) {                                             \
169         return ARM_DRIVER_ERROR_PARAMETER;                                    \
170     }                                                                         \
171                                                                               \
172     if (addr % FLASH_DEV.data->sector_size) {                                 \
173         return ARM_DRIVER_ERROR_PARAMETER;                                    \
174     }                                                                         \
175                                                                               \
176     FLASH_DEV.save_mpu_state(&FLASH_DEV);                                     \
177                                                                               \
178     flash_range_erase(addr, FLASH_DEV.data->sector_size);                     \
179                                                                               \
180     FLASH_DEV.restore_mpu_state();                                            \
181                                                                               \
182     return ARM_DRIVER_OK;                                                     \
183 }                                                                             \
184                                                                               \
185 static int32_t FLASH_DRIVER_NAME##_EraseChip(void)                            \
186 {                                                                             \
187     return ARM_DRIVER_ERROR_UNSUPPORTED;                                      \
188 }                                                                             \
189                                                                               \
190 static ARM_FLASH_INFO * FLASH_DRIVER_NAME##_GetInfo(void)                     \
191 {                                                                             \
192     return FLASH_DEV.data;                                                    \
193 }                                                                             \
194                                                                               \
195 ARM_DRIVER_FLASH FLASH_DRIVER_NAME = {                                        \
196     ARM_Flash_GetVersion,                                                     \
197     Pico_Driver_GetCapabilities,                                              \
198     FLASH_DRIVER_NAME##_Initialize,                                           \
199     ARM_Flash_Uninitialize,                                                   \
200     ARM_Flash_PowerControl,                                                   \
201     FLASH_DRIVER_NAME##_ReadData,                                             \
202     FLASH_DRIVER_NAME##_ProgramData,                                          \
203     FLASH_DRIVER_NAME##_EraseSector,                                          \
204     FLASH_DRIVER_NAME##_EraseChip,                                            \
205     ARM_Flash_GetStatus,                                                      \
206     FLASH_DRIVER_NAME##_GetInfo                                               \
207 };
208 
209 #endif /* __DRIVER_FLASH_RPI_H__ */
210