-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathmpfs250.h
More file actions
461 lines (383 loc) · 18.4 KB
/
mpfs250.h
File metadata and controls
461 lines (383 loc) · 18.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
/* mpfs250.h
*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef MPFS250_DEF_INCLUDED
#define MPFS250_DEF_INCLUDED
/* Generic RISC-V definitions are included at the end of this file
* (after PLIC_BASE is defined) to enable PLIC function declarations */
/* PolarFire SoC MPFS250T board specific configuration */
/* APB/AHB Peripheral Bus Clock Frequency (used for UART baud rate divisor)
* M-mode (out of reset, no PLL): 40 MHz
* S-mode (after HSS configures PLL): 150 MHz
*/
#ifndef MSS_APB_AHB_CLK
#ifdef WOLFBOOT_RISCV_MMODE
#define MSS_APB_AHB_CLK 40000000
#else
#define MSS_APB_AHB_CLK 150000000
#endif
#endif
/* CPU Core Clock Frequency (used for mcycle-based benchmarking)
* The E51 core runs at 2x the APB bus clock on reset.
* After HSS configures the PLL, CPU runs at 600 MHz. */
#ifndef MSS_CPU_CLK
#ifdef WOLFBOOT_RISCV_MMODE
#define MSS_CPU_CLK (MSS_APB_AHB_CLK * 2)
#else
#define MSS_CPU_CLK 600000000
#endif
#endif
/* Hardware Base Address */
#define SYSREG_BASE 0x20002000
/* Write "0xDEAD" to cause a full MSS reset*/
#define SYSREG_MSS_RESET_CR (*((volatile uint32_t*)(SYSREG_BASE + 0x18)))
/* Peripheral Subblock Clock Control Register (offset 0x84) */
#define SYSREG_SUBBLK_CLOCK_CR (*((volatile uint32_t*)(SYSREG_BASE + 0x84)))
#define SYSREG_SUBBLK_CLOCK_CR_ENVM (1U << 0)
#define SYSREG_SUBBLK_CLOCK_CR_MMC (1U << 3)
#define SYSREG_SUBBLK_CLOCK_CR_QSPI (1U << 19)
/* Peripheral Soft Reset Control Register (offset 0x88) */
#define SYSREG_SOFT_RESET_CR (*((volatile uint32_t*)(SYSREG_BASE + 0x88)))
/* MSS Peripheral control bits (shared by SUBBLK_CLOCK_CR and SOFT_RESET_CR) */
#define MSS_PERIPH_ENVM (1U << 0)
#define MSS_PERIPH_MMC (1U << 3)
#define MSS_PERIPH_MMUART0 (1U << 5)
#define MSS_PERIPH_MMUART1 (1U << 6)
#define MSS_PERIPH_MMUART2 (1U << 7)
#define MSS_PERIPH_MMUART3 (1U << 8)
#define MSS_PERIPH_MMUART4 (1U << 9)
#define MSS_PERIPH_QSPI (1U << 19)
/* UART */
#define MSS_UART0_LO_BASE 0x20000000UL
#define MSS_UART1_LO_BASE 0x20100000UL
#define MSS_UART2_LO_BASE 0x20102000UL
#define MSS_UART3_LO_BASE 0x20104000UL
#define MSS_UART4_LO_BASE 0x20106000UL
#define MSS_UART0_HI_BASE 0x28000000UL
#define MSS_UART1_HI_BASE 0x28100000UL
#define MSS_UART2_HI_BASE 0x28102000UL
#define MSS_UART3_HI_BASE 0x28104000UL
#define MSS_UART4_HI_BASE 0x28106000UL
/* UART base address table for per-hart access (LO addresses for M-mode) */
#ifndef __ASSEMBLER__
extern const unsigned long MSS_UART_BASE_ADDR[5];
#define UART_BASE_FOR_HART(hart) (MSS_UART_BASE_ADDR[(hart) < 5 ? (hart) : 0])
#endif /* __ASSEMBLER__ */
/* Debug UART port selection (0-4): M-mode defaults to UART0, S-mode to UART1 */
#ifndef DEBUG_UART_PORT
#ifdef WOLFBOOT_RISCV_MMODE
#define DEBUG_UART_PORT 0
#else
#define DEBUG_UART_PORT 1
#endif
#endif
/* Derive base address from port number */
#if DEBUG_UART_PORT == 0
#define DEBUG_UART_BASE MSS_UART0_LO_BASE
#elif DEBUG_UART_PORT == 1
#define DEBUG_UART_BASE MSS_UART1_LO_BASE
#elif DEBUG_UART_PORT == 2
#define DEBUG_UART_BASE MSS_UART2_LO_BASE
#elif DEBUG_UART_PORT == 3
#define DEBUG_UART_BASE MSS_UART3_LO_BASE
#elif DEBUG_UART_PORT == 4
#define DEBUG_UART_BASE MSS_UART4_LO_BASE
#else
#error "Invalid DEBUG_UART_PORT (must be 0-4)"
#endif
#define MMUART_RBR(base) *((volatile uint8_t*)((base)) + 0x00) /* Receiver buffer register */
#define MMUART_IER(base) *((volatile uint8_t*)((base)) + 0x04) /* Interrupt enable register */
#define MMUART_IIR(base) *((volatile uint8_t*)((base)) + 0x08) /* Interrupt ID register */
#define MMUART_LCR(base) *((volatile uint8_t*)((base)) + 0x0C) /* Line control register */
#define MMUART_MCR(base) *((volatile uint8_t*)((base)) + 0x10) /* Modem control register */
#define MMUART_LSR(base) *((volatile uint8_t*)((base)) + 0x14) /* Line status register */
#define MMUART_MM0(base) *((volatile uint8_t*)((base)) + 0x30) /* Mode register 0 */
#define MMUART_MM1(base) *((volatile uint8_t*)((base)) + 0x34) /* Mode register 1 */
#define MMUART_MM2(base) *((volatile uint8_t*)((base)) + 0x38) /* Mode register 2 */
#define MMUART_DFR(base) *((volatile uint8_t*)((base)) + 0x3C) /* Fractional divisor register */
#define MMUART_GFR(base) *((volatile uint8_t*)((base)) + 0x44) /* Global filter register */
#define MMUART_TTG(base) *((volatile uint8_t*)((base)) + 0x48) /* TX time guard register */
#define MMUART_RTO(base) *((volatile uint8_t*)((base)) + 0x4C) /* RX timeout register */
#define MMUART_DLR(base) *((volatile uint8_t*)((base)) + 0x80) /* Divisor latch LSB */
#define MMUART_DMR(base) *((volatile uint8_t*)((base)) + 0x84) /* Divisor latch MSB */
#define MMUART_THR(base) *((volatile uint8_t*)((base)) + 0x100) /* Transmitter holding register */
#define MMUART_FCR(base) *((volatile uint8_t*)((base)) + 0x104) /* FIFO control register */
/* LCR (Line Control Register) */
#define MSS_UART_DATA_8_BITS ((uint8_t)0x03)
#define MSS_UART_NO_PARITY ((uint8_t)0x00)
#define MSS_UART_ONE_STOP_BIT ((uint8_t)0x00)
/* LSR (Line Status Register) */
#define MSS_UART_DR ((uint8_t)0x01) /* Data ready */
#define MSS_UART_THRE ((uint8_t)0x20) /* Transmitter holding register empty */
#define ELIN_MASK (1U << 3) /* Enable LIN header detection */
#define EIRD_MASK (1U << 2) /* Enable IrDA modem */
#define EERR_MASK (1U << 0) /* Enable ERR / NACK during stop time */
#define RXRDY_TXRDYN_EN_MASK (1U << 0) /* Enable TXRDY and RXRDY signals */
#define CLEAR_RX_FIFO_MASK (1U << 1) /* Clear receiver FIFO */
#define CLEAR_TX_FIFO_MASK (1U << 2) /* Clear transmitter FIFO */
#define LOOP_MASK (1U << 4) /* Local loopback */
#define RLOOP_MASK (1U << 5) /* Remote loopback & Automatic echo*/
#define E_MSB_RX_MASK (1U << 0) /* MSB / LSB first for receiver */
#define E_MSB_TX_MASK (1U << 1) /* MSB / LSB first for transmitter */
#define EAFM_MASK (1U << 1) /* Enable 9-bit address flag mode */
#define ETTG_MASK (1U << 5) /* Enable transmitter time guard */
#define ERTO_MASK (1U << 6) /* Enable receiver time-out */
#define ESWM_MASK (1U << 3) /* Enable single wire half-duplex mode */
#define EFBR_MASK (1U << 7) /* Enable fractional baud rate mode */
/* Line Control register bit masks */
#define SB_MASK (1U << 6) /* Set break */
#define DLAB_MASK (1U << 7) /* Divisor latch access bit */
/* ============================================================================
* EMMC/SD Card Controller (Cadence SD4HC)
* Base Address: 0x20008000
* ============================================================================ */
#define EMMC_SD_BASE 0x20008000UL
/* ============================================================================
* System Controller Mailbox
* Control Base: 0x37020000
* Mailbox RAM: 0x37020800
*
* Used for system services like reading the device serial number.
* ============================================================================ */
#define SCBCTRL_BASE 0x37020000UL
#define SCBMBOX_BASE 0x37020800UL
/* System Services Control and Status Register offsets (from SCBCTRL_BASE) */
#define SERVICES_CR_OFFSET 0x50u
#define SERVICES_SR_OFFSET 0x54u
/* Control Register bits */
#define SERVICES_CR_REQ_MASK 0x01u
#define SERVICES_CR_COMMAND_SHIFT 16
/* Status Register bits */
#define SERVICES_SR_BUSY_MASK 0x02u
#define SERVICES_SR_STATUS_SHIFT 16
/* System Service command opcodes */
#define SYS_SERV_CMD_SERIAL_NUMBER 0x00u
/* Device serial number size in bytes */
#define DEVICE_SERIAL_NUMBER_SIZE 16
/* Timeout loop iteration counts (override at build time via CFLAGS) */
#ifndef MPFS_SCB_TIMEOUT
#define MPFS_SCB_TIMEOUT 10000 /* SCB mailbox polling */
#endif
#ifndef QSPI_TIMEOUT_TRIES
#define QSPI_TIMEOUT_TRIES 100000 /* QSPI controller/TX polling */
#endif
#ifndef QSPI_RX_TIMEOUT_TRIES
#define QSPI_RX_TIMEOUT_TRIES 1000000 /* QSPI RX polling (longer) */
#endif
/* System Controller register access */
#define SCBCTRL_REG(off) (*((volatile uint32_t*)(SCBCTRL_BASE + (off))))
#define SCBMBOX_REG(off) (*((volatile uint32_t*)(SCBMBOX_BASE + (off))))
#define SCBMBOX_BYTE(off) (*((volatile uint8_t*)(SCBMBOX_BASE + (off))))
/* System Controller Mailbox API */
#ifndef __ASSEMBLER__
int mpfs_scb_service_call(uint8_t opcode, const uint8_t *mb_data,
uint32_t mb_len, uint32_t timeout);
int mpfs_scb_read_mailbox(uint8_t *out, uint32_t len);
int mpfs_read_serial_number(uint8_t *serial);
#endif /* __ASSEMBLER__ */
/* Crypto Engine: Athena F5200 (200 MHz) */
#define ATHENA_BASE (SYSREG_BASE + 0x125000)
/* L2 Cache Controller (CACHE_CTRL @ 0x02010000) */
#define L2_CACHE_BASE 0x02010000UL
#define L2_CONFIG (*(volatile uint64_t*)(L2_CACHE_BASE + 0x000))
#define L2_WAY_ENABLE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x008))
#define L2_WAY_MASK_DMA (*(volatile uint64_t*)(L2_CACHE_BASE + 0x800))
#define L2_WAY_MASK_AXI4_PORT0 (*(volatile uint64_t*)(L2_CACHE_BASE + 0x808))
#define L2_WAY_MASK_AXI4_PORT1 (*(volatile uint64_t*)(L2_CACHE_BASE + 0x810))
#define L2_WAY_MASK_AXI4_PORT2 (*(volatile uint64_t*)(L2_CACHE_BASE + 0x818))
#define L2_WAY_MASK_AXI4_PORT3 (*(volatile uint64_t*)(L2_CACHE_BASE + 0x820))
#define L2_WAY_MASK_E51_DCACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x828))
#define L2_WAY_MASK_E51_ICACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x830))
#define L2_WAY_MASK_U54_1_DCACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x838))
#define L2_WAY_MASK_U54_1_ICACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x840))
#define L2_WAY_MASK_U54_2_DCACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x848))
#define L2_WAY_MASK_U54_2_ICACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x850))
#define L2_WAY_MASK_U54_3_DCACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x858))
#define L2_WAY_MASK_U54_3_ICACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x860))
#define L2_WAY_MASK_U54_4_DCACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x868))
#define L2_WAY_MASK_U54_4_ICACHE (*(volatile uint64_t*)(L2_CACHE_BASE + 0x870))
/* L2 Shutdown Control Register */
#define SYSREG_L2_SHUTDOWN_CR (*(volatile uint32_t*)(SYSREG_BASE + 0x174))
/* L2 Cache/Scratchpad constants */
#define L2_NUM_CACHE_WAYS 8 /* Ways 0-7 are cache */
#define L2_NUM_SCRATCH_WAYS 4 /* Ways 8-11 are scratchpad */
#define L2_WAY_BYTE_LENGTH 0x20000 /* 128KB per way */
#define L2_SCRATCH_BASE 0x0A000000UL
#define L2_SCRATCH_SIZE (L2_NUM_SCRATCH_WAYS * L2_WAY_BYTE_LENGTH)
#define L2_WAY_ENABLE_RESET 0x01
#define L2_WAY_ENABLE_ALL_CACHE 0xFF
#define L2_WAY_ENABLE_WITH_SCRATCH 0x0FFF
#define L2_WAY_MASK_CACHE_ONLY 0xFF
/* CLINT - Core Local Interruptor */
#ifndef CLINT_BASE
#define CLINT_BASE 0x02000000UL
#endif
/* RTC Clock Frequency (1 MHz after divisor) */
#define RTC_CLOCK_FREQ 1000000UL
/* In M-mode CLINT MTIME is not running without HSS; use mcycle (CPU clock) instead.
* In S-mode MTIME runs at 1 MHz (default RISCV_SMODE_TIMER_FREQ). */
#if defined(WOLFBOOT_RISCV_MMODE) && !defined(RISCV_SMODE_TIMER_FREQ)
#define RISCV_SMODE_TIMER_FREQ MSS_CPU_CLK
#endif
/* Hart Local Storage (HLS) - per-hart communication structure, 64 bytes at top of stack */
#define HLS_DEBUG_AREA_SIZE 64
#ifndef __ASSEMBLER__
typedef struct {
volatile uint32_t in_wfi_indicator; /* 0x00: Hart status indicator */
volatile uint32_t my_hart_id; /* 0x04: Hart ID */
volatile uint32_t shared_mem_marker; /* 0x08: Init marker */
volatile uint32_t shared_mem_status; /* 0x0C: Status */
volatile uint64_t* shared_mem; /* 0x10: Shared memory pointer */
volatile uint64_t reserved[5]; /* 0x18: Reserved/padding to 64 bytes */
} HLS_DATA; /* 64 bytes total */
#endif /* __ASSEMBLER__ */
#define HLS_MAIN_HART_STARTED 0x12344321UL
#define HLS_OTHER_HART_IN_WFI 0x12345678UL
/* Number of harts on MPFS */
#define MPFS_NUM_HARTS 5
#define MPFS_FIRST_HART 0 /* E51 is hart 0 */
#define MPFS_FIRST_U54_HART 1 /* First U54 is hart 1 */
#define MPFS_LAST_U54_HART 4 /* Last U54 is hart 4 */
/* Stack configuration per hart */
#ifndef STACK_SIZE_PER_HART
#define STACK_SIZE_PER_HART 8192
#endif
/* Multi-hart function declarations */
#ifndef __ASSEMBLER__
#ifdef DEBUG_UART
void uart_init(void);
void uart_write(const char* buf, unsigned int sz);
#endif
#ifdef WOLFBOOT_RISCV_MMODE
int mpfs_wake_secondary_harts(void);
void secondary_hart_entry(unsigned long hartid, HLS_DATA* hls);
void uart_init_hart(unsigned long hartid);
void uart_write_hart(unsigned long hartid, const char* buf, unsigned int sz);
#endif
#endif /* __ASSEMBLER__ */
/* PLIC - Platform-Level Interrupt Controller (base 0x0C000000, 64MB) */
#define PLIC_BASE 0x0C000000UL
#define PLIC_SIZE 0x04000000UL
#define PLIC_NUM_SOURCES 186
#define PLIC_NUM_HARTS 5
#define PLIC_NUM_CONTEXTS 10
#define OFFSET_TO_MSS_GLOBAL_INTS 13
#define PLIC_INT_MMC_MAIN 88
#ifdef EXT_FLASH
/* QSPI Flash Controller
*
* Two CoreQSPI v2 controllers with identical register layouts:
* SC QSPI (MPFS_SC_SPI=1, default): 0x37020100 — fabric-connected flash
* MSS QSPI (MPFS_SC_SPI=0): 0x21000000 — MSS QSPI pins
*/
/* QSPI Controller Base Address */
#ifndef QSPI_BASE
#ifdef MPFS_SC_SPI
#define QSPI_BASE 0x37020100u /* SC QSPI Controller (fabric-connected flash) */
#else
#define QSPI_BASE 0x21000000u /* MSS QSPI Controller (external flash) */
#endif
#endif
/* QSPI Register Offsets */
#define QSPI_CONTROL (*(volatile uint32_t *)(QSPI_BASE + 0x00))
#define QSPI_FRAMES (*(volatile uint32_t *)(QSPI_BASE + 0x04))
#define QSPI_IEN (*(volatile uint32_t *)(QSPI_BASE + 0x0C))
#define QSPI_STATUS (*(volatile uint32_t *)(QSPI_BASE + 0x10))
#define QSPI_DIRECT (*(volatile uint32_t *)(QSPI_BASE + 0x14))
#define QSPI_ADDRUP (*(volatile uint32_t *)(QSPI_BASE + 0x18))
#define QSPI_RX_DATA (*(volatile uint8_t *)(QSPI_BASE + 0x40))
#define QSPI_TX_DATA (*(volatile uint8_t *)(QSPI_BASE + 0x44))
#define QSPI_X4_RX_DATA (*(volatile uint32_t *)(QSPI_BASE + 0x48))
#define QSPI_X4_TX_DATA (*(volatile uint32_t *)(QSPI_BASE + 0x4C))
#define QSPI_FRAMESUP (*(volatile uint32_t *)(QSPI_BASE + 0x50))
/* QSPI Control Register Bits */
#define QSPI_CTRL_EN_OFFSET 0
#define QSPI_CTRL_XIP_OFFSET 2
#define QSPI_CTRL_XIPADDR_OFFSET 3
#define QSPI_CTRL_CLKIDLE_OFFSET 10
#define QSPI_CTRL_SAMPLE_OFFSET 11
#define QSPI_CTRL_QMODE0_OFFSET 13
#define QSPI_CTRL_QMODE12_OFFSET 14
#define QSPI_CTRL_FLAGSX4_OFFSET 16
#define QSPI_CTRL_CLKRATE_OFFSET 24
#define QSPI_CTRL_EN (1u << QSPI_CTRL_EN_OFFSET)
#define QSPI_CTRL_XIP (1u << QSPI_CTRL_XIP_OFFSET)
#define QSPI_CTRL_CLKIDLE (1u << QSPI_CTRL_CLKIDLE_OFFSET)
#define QSPI_CTRL_SAMPLE_SCK (0x0u << QSPI_CTRL_SAMPLE_OFFSET)
/* QSPI Frames Register Bits */
#define QSPI_FRAMES_TOTALBYTES_OFFSET 0
#define QSPI_FRAMES_CMDBYTES_OFFSET 16
#define QSPI_FRAMES_QSPI_OFFSET 25
#define QSPI_FRAMES_IDLE_OFFSET 26
#define QSPI_FRAMES_FBYTE_OFFSET 30
#define QSPI_FRAMES_FWORD_OFFSET 31
#define QSPI_FRAMES_TOTALBYTES_MASK (0xFFFFu << QSPI_FRAMES_TOTALBYTES_OFFSET)
#define QSPI_FRAMES_CMDBYTES_MASK (0x1FFu << QSPI_FRAMES_CMDBYTES_OFFSET)
#define QSPI_FRAMES_QSPI (1u << QSPI_FRAMES_QSPI_OFFSET)
#define QSPI_FRAMES_IDLE_MASK (0xFu << QSPI_FRAMES_IDLE_OFFSET)
/* QSPI Status Register Bits */
#define QSPI_STATUS_TXDONE (1u << 0)
#define QSPI_STATUS_RXDONE (1u << 1)
#define QSPI_STATUS_RXAVAIL (1u << 2)
#define QSPI_STATUS_TXAVAIL (1u << 3)
#define QSPI_STATUS_READY (1u << 7)
/* QSPI Clock Configuration */
#define QSPI_CLK_DIV_2 0x01u
#define QSPI_CLK_DIV_4 0x02u
#define QSPI_CLK_DIV_6 0x03u
#define QSPI_CLK_DIV_8 0x04u
#define QSPI_CLK_DIV_10 0x05u
#define QSPI_CLK_DIV_12 0x06u
#define QSPI_CLK_DIV_30 0x0Fu /* ~5 MHz from 150 MHz APB */
/* Micron MT25QL01G Flash Commands */
#define QSPI_CMD_READ_ID_OPCODE 0x9Fu /* JEDEC ID Read */
#define QSPI_CMD_MIO_READ_ID_OPCODE 0xAFu /* Multiple IO Read ID */
#define QSPI_CMD_READ_STATUS_OPCODE 0x05u /* Read Status Register */
#define QSPI_CMD_WRITE_ENABLE_OPCODE 0x06u /* Write Enable */
#define QSPI_CMD_WRITE_DISABLE_OPCODE 0x04u /* Write Disable */
#define QSPI_CMD_4BYTE_READ_OPCODE 0x13u /* 4-byte address read */
#define QSPI_CMD_4BYTE_FAST_READ_OPCODE 0x0Cu /* 4-byte fast read */
#define QSPI_CMD_4BYTE_QUAD_READ_OPCODE 0xECu /* 4-byte quad I/O read */
#define QSPI_CMD_4BYTE_PAGE_PROG_OPCODE 0x12u /* 4-byte page program */
#define QSPI_CMD_4BYTE_SECTOR_ERASE 0xDCu /* 4-byte 64KB sector erase */
#define QSPI_CMD_ENTER_4BYTE_MODE 0xB7u /* Enter 4-byte address mode */
#define QSPI_CMD_EXIT_4BYTE_MODE 0xE9u /* Exit 4-byte address mode */
/* Flash Geometry - Micron MT25QL01GBBB (128MB) */
#ifndef FLASH_DEVICE_SIZE
#define FLASH_DEVICE_SIZE (128 * 1024 * 1024) /* 128MB (1Gb) */
#endif
#ifndef FLASH_PAGE_SIZE
#define FLASH_PAGE_SIZE 256 /* 256 bytes */
#endif
#ifndef FLASH_SECTOR_SIZE
#define FLASH_SECTOR_SIZE (64 * 1024) /* 64KB sectors */
#endif
/* QSPI Transfer Modes */
#define QSPI_MODE_WRITE 0
#define QSPI_MODE_READ 1
/* I/O fence: ensure MMIO store reaches the peripheral before the next read.
* Required on RISC-V RVWMO to prevent stale TXAVAIL reads after TX writes. */
#define QSPI_IO_FENCE() __asm__ __volatile__("fence iorw, iorw" ::: "memory")
/* Function declarations for QSPI (when EXT_FLASH enabled) */
#ifndef __ASSEMBLER__
int qspi_init(void);
#endif /* __ASSEMBLER__ */
#endif /* EXT_FLASH */
#endif /* MPFS250_DEF_INCLUDED */