mirror of https://github.com/wolfSSL/wolfBoot.git
613 lines
26 KiB
C
613 lines
26 KiB
C
/* versal.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
|
|
*
|
|
* AMD Versal ACAP HAL definitions for wolfBoot
|
|
* Target: VMK180 Evaluation Board (VM1802 Versal Prime)
|
|
*/
|
|
|
|
#ifndef _VERSAL_H_
|
|
#define _VERSAL_H_
|
|
|
|
/* Only include C headers when compiling C code, not assembly */
|
|
#ifndef __ASSEMBLER__
|
|
#include <stdint.h>
|
|
#endif /* __ASSEMBLER__ */
|
|
|
|
/* ============================================================================
|
|
* Exception Level Configuration
|
|
* ============================================================================
|
|
* Versal PLM (Platform Loader Manager) can hand off at EL3, EL2, or EL1
|
|
* depending on configuration. Default is EL2 (hypervisor mode).
|
|
*/
|
|
#ifndef USE_BUILTIN_STARTUP
|
|
|
|
#ifndef EL3_SECURE
|
|
#define EL3_SECURE 0
|
|
#endif
|
|
#ifndef EL2_HYPERVISOR
|
|
#define EL2_HYPERVISOR 1
|
|
#endif
|
|
#ifndef EL1_NONSECURE
|
|
#define EL1_NONSECURE 1
|
|
#endif
|
|
|
|
#ifndef HYP_GUEST
|
|
#define HYP_GUEST 0
|
|
#endif
|
|
|
|
#ifndef FPU_TRAP
|
|
#define FPU_TRAP 0
|
|
#endif
|
|
|
|
/* ARM Errata */
|
|
#define CONFIG_ARM_ERRATA_855873 1
|
|
|
|
/* BL31-applied errata/CVEs:
|
|
* ARM Trusted Firmware (BL31) applies these CPU workarounds at EL3:
|
|
* - Erratum 859971
|
|
* - Erratum 1319367
|
|
* - CVE-2017-5715 (Spectre V2)
|
|
* - CVE-2018-3639 (SSB)
|
|
* - CVE-2022-23960
|
|
* Note: Do not modify CPUACTLR_EL1 in application code without preserving these.
|
|
*/
|
|
|
|
#endif /* USE_BUILTIN_STARTUP */
|
|
|
|
/* ============================================================================
|
|
* Versal-specific Boot Defaults
|
|
* ============================================================================
|
|
* SKIP_GIC_INIT: Versal uses GICv3 (not GICv2 like ZynqMP).
|
|
* BL31 handles GIC initialization, so skip gicv2_init_secure().
|
|
*
|
|
* Boot Exception Level Configuration (mutually exclusive):
|
|
* BOOT_EL1: wolfBoot runs at EL2, but applications (Linux, most bare-metal)
|
|
* are transitioned to EL1 before jumping (default)
|
|
* BOOT_EL2: Applications boot at EL2 (for hypervisors/RTOSes that
|
|
* expect to run at EL2)
|
|
*
|
|
* Default: BOOT_EL1 (most applications expect EL1)
|
|
*/
|
|
#ifndef SKIP_GIC_INIT
|
|
#define SKIP_GIC_INIT 1
|
|
#endif
|
|
|
|
#if !defined(BOOT_EL1) && !defined(BOOT_EL2)
|
|
#define BOOT_EL1 1
|
|
#endif
|
|
|
|
#if defined(BOOT_EL1) && defined(BOOT_EL2)
|
|
#error "BOOT_EL1 and BOOT_EL2 are mutually exclusive"
|
|
#endif
|
|
|
|
|
|
/* ============================================================================
|
|
* Memory Map
|
|
* ============================================================================
|
|
* Versal memory map (simplified):
|
|
* 0x0000_0000 - 0x7FFF_FFFF : DDR Low (2GB)
|
|
* 0x8_0000_0000 - ... : DDR High (extended)
|
|
* 0xF000_0000 - 0xFFFF_FFFF : LPD/FPD Peripherals
|
|
*/
|
|
|
|
/* DDR Memory */
|
|
#define VERSAL_DDR_0_BASE 0x00000000UL
|
|
#define VERSAL_DDR_0_HIGH 0x7FFFFFFFUL
|
|
#define VERSAL_DDR_1_BASE 0x800000000ULL
|
|
#define VERSAL_DDR_1_HIGH 0x87FFFFFFFULL
|
|
|
|
/* Application load address and cache flush size for hal_prepare_boot() */
|
|
#ifndef WOLFBOOT_LOAD_ADDRESS
|
|
#define WOLFBOOT_LOAD_ADDRESS 0x10000000UL
|
|
#endif
|
|
#define CACHE_LINE_SIZE 64
|
|
#define APP_CACHE_FLUSH_SIZE (1 * 1024 * 1024) /* 1MB */
|
|
|
|
/* DDR defines for MMU table setup (used by boot_aarch64_start.S)
|
|
* These macros enable proper DDR mapping in the page tables.
|
|
* Without these, the MMU tables would have DDR_0_REG=0 and no DDR mapped! */
|
|
#define XPAR_PSU_DDR_0_S_AXI_BASEADDR VERSAL_DDR_0_BASE
|
|
#define XPAR_PSU_DDR_0_S_AXI_HIGHADDR VERSAL_DDR_0_HIGH
|
|
|
|
|
|
/* ============================================================================
|
|
* UART (ARM PL011 UART - UARTPSV)
|
|
* ============================================================================
|
|
* Versal uses ARM PL011 UART (different from ZynqMP Cadence UART!)
|
|
* Based on AMD/Xilinx xuartpsv_hw.h
|
|
*/
|
|
|
|
#define VERSAL_UART0_BASE 0xFF000000UL
|
|
#define VERSAL_UART1_BASE 0xFF010000UL
|
|
|
|
/* Select UART based on DEBUG_UART_NUM */
|
|
#if defined(DEBUG_UART_NUM) && DEBUG_UART_NUM == 1
|
|
#define DEBUG_UART_BASE VERSAL_UART1_BASE
|
|
#else
|
|
#define DEBUG_UART_BASE VERSAL_UART0_BASE
|
|
#endif
|
|
|
|
/* UART Register Offsets (ARM PL011) */
|
|
#define UART_DR_OFFSET 0x00 /* Data Register (TX/RX FIFO) */
|
|
#define UART_RSR_OFFSET 0x04 /* Receive Status / Error Clear */
|
|
#define UART_FR_OFFSET 0x18 /* Flag Register (Status) */
|
|
#define UART_ILPR_OFFSET 0x20 /* IrDA Low-Power Counter */
|
|
#define UART_IBRD_OFFSET 0x24 /* Integer Baud Rate Divisor */
|
|
#define UART_FBRD_OFFSET 0x28 /* Fractional Baud Rate Divisor */
|
|
#define UART_LCR_OFFSET 0x2C /* Line Control Register */
|
|
#define UART_CR_OFFSET 0x30 /* Control Register */
|
|
#define UART_IFLS_OFFSET 0x34 /* Interrupt FIFO Level Select */
|
|
#define UART_IMSC_OFFSET 0x38 /* Interrupt Mask Set/Clear */
|
|
#define UART_RIS_OFFSET 0x3C /* Raw Interrupt Status */
|
|
#define UART_MIS_OFFSET 0x40 /* Masked Interrupt Status */
|
|
#define UART_ICR_OFFSET 0x44 /* Interrupt Clear Register */
|
|
#define UART_DMACR_OFFSET 0x48 /* DMA Control Register */
|
|
|
|
/* UART Register Access Macros */
|
|
#define UART_REG(offset) (*((volatile uint32_t*)(DEBUG_UART_BASE + (offset))))
|
|
|
|
#define UART_DR UART_REG(UART_DR_OFFSET)
|
|
#define UART_RSR UART_REG(UART_RSR_OFFSET)
|
|
#define UART_FR UART_REG(UART_FR_OFFSET)
|
|
#define UART_IBRD UART_REG(UART_IBRD_OFFSET)
|
|
#define UART_FBRD UART_REG(UART_FBRD_OFFSET)
|
|
#define UART_LCR UART_REG(UART_LCR_OFFSET)
|
|
#define UART_CR UART_REG(UART_CR_OFFSET)
|
|
#define UART_IFLS UART_REG(UART_IFLS_OFFSET)
|
|
#define UART_IMSC UART_REG(UART_IMSC_OFFSET)
|
|
#define UART_ICR UART_REG(UART_ICR_OFFSET)
|
|
|
|
/* Flag Register (UARTFR) bits - Status */
|
|
#define UART_FR_RI (1UL << 8) /* Ring indicator */
|
|
#define UART_FR_TXFE (1UL << 7) /* TX FIFO empty */
|
|
#define UART_FR_RXFF (1UL << 6) /* RX FIFO full */
|
|
#define UART_FR_TXFF (1UL << 5) /* TX FIFO full */
|
|
#define UART_FR_RXFE (1UL << 4) /* RX FIFO empty */
|
|
#define UART_FR_BUSY (1UL << 3) /* UART busy */
|
|
#define UART_FR_DCD (1UL << 2) /* Data carrier detect */
|
|
#define UART_FR_DSR (1UL << 1) /* Data set ready */
|
|
#define UART_FR_CTS (1UL << 0) /* Clear to send */
|
|
|
|
/* Control Register (UARTCR) bits */
|
|
#define UART_CR_CTSEN (1UL << 15) /* CTS hardware flow control */
|
|
#define UART_CR_RTSEN (1UL << 14) /* RTS hardware flow control */
|
|
#define UART_CR_RTS (1UL << 11) /* Request to send */
|
|
#define UART_CR_DTR (1UL << 10) /* Data transmit ready */
|
|
#define UART_CR_RXE (1UL << 9) /* Receive enable */
|
|
#define UART_CR_TXE (1UL << 8) /* Transmit enable */
|
|
#define UART_CR_LBE (1UL << 7) /* Loopback enable */
|
|
#define UART_CR_UARTEN (1UL << 0) /* UART enable */
|
|
|
|
/* Line Control Register (UARTLCR) bits */
|
|
#define UART_LCR_SPS (1UL << 7) /* Stick parity select */
|
|
#define UART_LCR_WLEN_MASK (3UL << 5) /* Word length mask */
|
|
#define UART_LCR_WLEN_8 (3UL << 5) /* 8 data bits */
|
|
#define UART_LCR_WLEN_7 (2UL << 5) /* 7 data bits */
|
|
#define UART_LCR_WLEN_6 (1UL << 5) /* 6 data bits */
|
|
#define UART_LCR_WLEN_5 (0UL << 5) /* 5 data bits */
|
|
#define UART_LCR_FEN (1UL << 4) /* FIFO enable */
|
|
#define UART_LCR_STP2 (1UL << 3) /* Two stop bits */
|
|
#define UART_LCR_EPS (1UL << 2) /* Even parity select */
|
|
#define UART_LCR_PEN (1UL << 1) /* Parity enable */
|
|
#define UART_LCR_BRK (1UL << 0) /* Send break */
|
|
|
|
/* Interrupt FIFO Level Select (UARTIFLS) */
|
|
#define UART_IFLS_RXIFLSEL_1_8 (0UL << 3) /* RX FIFO 1/8 full */
|
|
#define UART_IFLS_RXIFLSEL_1_4 (1UL << 3) /* RX FIFO 1/4 full */
|
|
#define UART_IFLS_RXIFLSEL_1_2 (2UL << 3) /* RX FIFO 1/2 full */
|
|
#define UART_IFLS_TXIFLSEL_1_8 (0UL << 0) /* TX FIFO 1/8 full */
|
|
#define UART_IFLS_TXIFLSEL_1_4 (1UL << 0) /* TX FIFO 1/4 full */
|
|
#define UART_IFLS_TXIFLSEL_1_2 (2UL << 0) /* TX FIFO 1/2 full */
|
|
|
|
/* Interrupt bits (for IMSC, RIS, MIS, ICR) */
|
|
#define UART_INT_OE (1UL << 10) /* Overrun error */
|
|
#define UART_INT_BE (1UL << 9) /* Break error */
|
|
#define UART_INT_PE (1UL << 8) /* Parity error */
|
|
#define UART_INT_FE (1UL << 7) /* Framing error */
|
|
#define UART_INT_RT (1UL << 6) /* Receive timeout */
|
|
#define UART_INT_TX (1UL << 5) /* Transmit */
|
|
#define UART_INT_RX (1UL << 4) /* Receive */
|
|
#define UART_INT_ALL 0x7FFU /* All interrupts */
|
|
|
|
/* UART Configuration */
|
|
#ifndef UART_CLK_REF
|
|
#define UART_CLK_REF 100000000UL /* 100 MHz reference clock */
|
|
#endif
|
|
|
|
#ifndef DEBUG_UART_BAUD
|
|
#define DEBUG_UART_BAUD 115200
|
|
#endif
|
|
|
|
/* ============================================================================
|
|
* PMC_IOU_SLCR - MIO Pin Configuration
|
|
* ============================================================================
|
|
* Required for JTAG boot mode where PLM doesn't run
|
|
*/
|
|
#define PMC_IOU_SLCR_BASE 0xF1060000UL
|
|
|
|
/* MIO Pin registers - each MIO pin has its own 4-byte register */
|
|
#define PMC_IOU_SLCR_MIO_PIN(n) (*((volatile uint32_t*)(PMC_IOU_SLCR_BASE + 0x0 + ((n) * 4))))
|
|
|
|
/* MIO Pin register bits */
|
|
#define MIO_PIN_L0_SEL_MASK (0x1UL << 0) /* Level 0 MUX select */
|
|
#define MIO_PIN_L1_SEL_MASK (0x1UL << 1) /* Level 1 MUX select */
|
|
#define MIO_PIN_L2_SEL_MASK (0x3UL << 2) /* Level 2 MUX select */
|
|
#define MIO_PIN_L3_SEL_MASK (0x7UL << 4) /* Level 3 MUX select */
|
|
#define MIO_PIN_TRI_ENABLE (0x1UL << 8) /* Tri-state enable (input) */
|
|
#define MIO_PIN_PULLUP (0x1UL << 12) /* Pull-up enable */
|
|
#define MIO_PIN_SCHMITT_ENABLE (0x1UL << 13) /* Schmitt trigger enable */
|
|
#define MIO_PIN_SLOW_SLEW (0x0UL << 14) /* Slow slew rate */
|
|
#define MIO_PIN_FAST_SLEW (0x1UL << 14) /* Fast slew rate */
|
|
|
|
/* UART0 default MIO pins on VMK180: MIO 0 (RX), MIO 1 (TX)
|
|
* L3_SEL = 1 selects UART function */
|
|
#define MIO_UART0_RX_PIN 0 /* MIO0 = UART0 RX */
|
|
#define MIO_UART0_TX_PIN 1 /* MIO1 = UART0 TX */
|
|
#define MIO_UART1_RX_PIN 4 /* MIO4 = UART1 RX */
|
|
#define MIO_UART1_TX_PIN 5 /* MIO5 = UART1 TX */
|
|
|
|
/* MIO configuration for UART TX pin: Output, UART function (L3_SEL=1) */
|
|
#define MIO_UART_TX_CFG (0x1UL << 4) /* L3_SEL = 1 for UART */
|
|
/* MIO configuration for UART RX pin: Input, UART function (L3_SEL=1) */
|
|
#define MIO_UART_RX_CFG ((0x1UL << 4) | MIO_PIN_TRI_ENABLE)
|
|
|
|
/* ============================================================================
|
|
* CRL (Clock Reset LPD) - For UART clock/reset control
|
|
* ============================================================================
|
|
* Register offsets verified from Xilinx lpd_data.cdo
|
|
*/
|
|
#define VERSAL_CRL_BASE 0xFF5E0000UL
|
|
|
|
/* UART Reference Clock Control - from lpd_data.cdo line 176 */
|
|
#define CRL_UART0_REF_CTRL (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0128)))
|
|
#define CRL_UART1_REF_CTRL (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x012C)))
|
|
|
|
/* SD/SDIO Reference Clock Control */
|
|
#define CRL_SDIO0_REF_CTRL (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0104)))
|
|
#define CRL_SDIO1_REF_CTRL (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0108)))
|
|
|
|
/* UART Reset Control - from lpd_data.cdo line 258 */
|
|
#define CRL_RST_UART0 (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0318)))
|
|
#define CRL_RST_UART1 (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x031C)))
|
|
#define CRL_RST_UART0_BIT (1UL << 0)
|
|
#define CRL_RST_UART1_BIT (1UL << 0) /* Each UART has its own register */
|
|
|
|
/* SD/SDIO Reset Control */
|
|
#define CRL_RST_SDIO0 (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0324)))
|
|
#define CRL_RST_SDIO1 (*((volatile uint32_t*)(VERSAL_CRL_BASE + 0x0328)))
|
|
#define CRL_RST_SDIO_BIT (1UL << 0)
|
|
|
|
/* Backward compatibility alias */
|
|
#define CRL_RST_UART CRL_RST_UART0
|
|
|
|
/* Clock Reference Control bits */
|
|
#define CRL_CLK_CLKACT (1UL << 25) /* Clock active */
|
|
#define CRL_CLK_DIVISOR_MASK (0x3FFUL << 8) /* Divisor field */
|
|
|
|
|
|
/* ============================================================================
|
|
* System Timer (ARM Generic Timer)
|
|
* ============================================================================
|
|
* Versal uses ARM Generic Timer accessed via system registers
|
|
*/
|
|
|
|
/* Timer frequency (typically configured by PLM) */
|
|
#ifndef TIMER_CLK_FREQ
|
|
#define TIMER_CLK_FREQ 100000000UL /* 100 MHz default */
|
|
#endif
|
|
|
|
|
|
/* ============================================================================
|
|
* GIC (Generic Interrupt Controller)
|
|
* ============================================================================
|
|
*/
|
|
#define VERSAL_GIC_BASE 0xF9000000UL
|
|
#define VERSAL_GICD_BASE (VERSAL_GIC_BASE + 0x00000) /* Distributor */
|
|
#define VERSAL_GICC_BASE (VERSAL_GIC_BASE + 0x40000) /* CPU Interface */
|
|
#define VERSAL_GICH_BASE (VERSAL_GIC_BASE + 0x60000) /* Virtual Interface Control */
|
|
#define VERSAL_GICV_BASE (VERSAL_GIC_BASE + 0x80000) /* Virtual CPU Interface */
|
|
|
|
|
|
/* ============================================================================
|
|
* Clock and Reset (CRF - FPD only, CRL defined above)
|
|
* ============================================================================
|
|
*/
|
|
#define VERSAL_CRF_BASE 0xFD1A0000UL /* Clock and Reset FPD */
|
|
|
|
|
|
/* ============================================================================
|
|
* PMC (Platform Management Controller)
|
|
* ============================================================================
|
|
* The PMC is the security controller in Versal (replaces CSU from ZynqMP)
|
|
*/
|
|
#define VERSAL_PMC_GLOBAL_BASE 0xF1110000UL
|
|
#define VERSAL_PMC_TAP_BASE 0xF11A0000UL
|
|
|
|
|
|
/* ============================================================================
|
|
* QSPI (Quad SPI) Flash Controller - GQSPI
|
|
* ============================================================================
|
|
* The Versal GQSPI controller is derived from the ZynqMP GQSPI IP block.
|
|
* VMK180 uses dual parallel MT25QU01GBBB (128MB each, 256MB total).
|
|
*
|
|
* Key differences from ZynqMP (see hal/zynq.c for comparison):
|
|
*
|
|
* 1. BASE ADDRESS:
|
|
* - ZynqMP: 0xFF0F0000
|
|
* - Versal: 0xF1030000
|
|
*
|
|
* 2. TAP DELAY BYPASS REGISTER:
|
|
* - ZynqMP: Located in IOU_SLCR block at 0xFF180390
|
|
* - Versal: Integrated in QSPI block at BASE + 0x03C
|
|
*
|
|
* 3. INITIALIZATION:
|
|
* - ZynqMP: Full init including FIFO reset and loopback delay tuning
|
|
* - Versal: Preserves PLM configuration, only drains RX FIFO
|
|
* (PLM already configured clocks, MIO, and controller)
|
|
*
|
|
* 4. CLOCK CONFIGURATION:
|
|
* - Both use same divisor formula: QSPI_CLK = REF_CLK / (2 << DIV)
|
|
* - Default: 300MHz ref, DIV=1 -> 75MHz (within MT25QU01G 133MHz spec)
|
|
*
|
|
* 5. REGISTER LAYOUT:
|
|
* - Identical offsets from base (+0x100 for GQSPI, +0x800 for DMA)
|
|
* - Same GenFIFO format, interrupt bits, and DMA interface
|
|
*
|
|
* 6. BUILD OPTIONS (same as ZynqMP):
|
|
* - GQSPI_MODE_IO: Use polling instead of DMA (DMA is default)
|
|
* - GQPI_USE_DUAL_PARALLEL: Enable dual parallel flash striping
|
|
* - GQPI_USE_4BYTE_ADDR: Enable 4-byte addressing for >16MB flash
|
|
* - GQSPI_CLK_DIV: Clock divider (0-7)
|
|
* - DEBUG_QSPI: Enable verbose debug logging
|
|
*/
|
|
#define VERSAL_QSPI_BASE 0xF1030000UL
|
|
|
|
/* QSPI Enable Register (at base, not +0x100) */
|
|
#define QSPI_EN_REG (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x14)))
|
|
|
|
/* GQSPI Registers (at offset 0x100 from QSPI base) */
|
|
#define GQSPI_CFG (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x100)))
|
|
#define GQSPI_ISR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x104)))
|
|
#define GQSPI_IER (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x108)))
|
|
#define GQSPI_IDR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x10C)))
|
|
#define GQSPI_IMR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x110)))
|
|
#define GQSPI_EN (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x114)))
|
|
#define GQSPI_TXD (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x11C)))
|
|
#define GQSPI_RXD (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x120)))
|
|
#define GQSPI_TX_THRESH (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x128)))
|
|
#define GQSPI_RX_THRESH (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x12C)))
|
|
#define GQSPI_GPIO (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x130)))
|
|
#define GQSPI_LPBK_DLY_ADJ (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x138)))
|
|
#define GQSPI_GEN_FIFO (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x140)))
|
|
#define GQSPI_SEL (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x144)))
|
|
#define GQSPI_FIFO_CTRL (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x14C)))
|
|
#define GQSPI_GF_THRESH (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x150)))
|
|
#define GQSPI_POLL_CFG (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x154)))
|
|
#define GQSPI_P_TIMEOUT (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x158)))
|
|
#define GQSPI_XFER_STS (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x15C)))
|
|
#define GQSPI_DATA_DLY_ADJ (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x1F8)))
|
|
#define GQSPI_MOD_ID (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x1FC)))
|
|
|
|
/* DMA Registers (at offset 0x800 from QSPI base) */
|
|
#define GQSPIDMA_DST (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x800)))
|
|
#define GQSPIDMA_SIZE (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x804)))
|
|
#define GQSPIDMA_STS (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x808)))
|
|
#define GQSPIDMA_CTRL (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x80C)))
|
|
#define GQSPIDMA_ISR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x814)))
|
|
#define GQSPIDMA_IER (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x818)))
|
|
#define GQSPIDMA_IDR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x81C)))
|
|
#define GQSPIDMA_IMR (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x820)))
|
|
#define GQSPIDMA_CTRL2 (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x824)))
|
|
#define GQSPIDMA_DST_MSB (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x828)))
|
|
|
|
/* Tap Delay Bypass Register - Versal specific location */
|
|
#define IOU_TAPDLY_BYPASS (*((volatile uint32_t*)(VERSAL_QSPI_BASE + 0x03C)))
|
|
#define IOU_TAPDLY_BYPASS_LQSPI_RX (1UL << 2)
|
|
|
|
/* GQSPI_CFG: Configuration register bits */
|
|
#define GQSPI_CFG_CLK_POL (1UL << 1)
|
|
#define GQSPI_CFG_CLK_PH (1UL << 2)
|
|
#define GQSPI_CFG_BAUD_RATE_DIV_MASK (7UL << 3)
|
|
#define GQSPI_CFG_BAUD_RATE_DIV(d) (((d) << 3) & GQSPI_CFG_BAUD_RATE_DIV_MASK)
|
|
#define GQSPI_CFG_WP_HOLD (1UL << 19)
|
|
#define GQSPI_CFG_EN_POLL_TIMEOUT (1UL << 20)
|
|
#define GQSPI_CFG_ENDIAN (1UL << 26)
|
|
#define GQSPI_CFG_START_GEN_FIFO (1UL << 28)
|
|
#define GQSPI_CFG_GEN_FIFO_START_MODE (1UL << 29)
|
|
#define GQSPI_CFG_MODE_EN_MASK (3UL << 30)
|
|
#define GQSPI_CFG_MODE_EN_IO (0UL << 30)
|
|
#define GQSPI_CFG_MODE_EN_DMA (2UL << 30)
|
|
|
|
/* GQSPI_ISR/IER/IDR: Interrupt bits */
|
|
#define GQSPI_IXR_POLL_TIME_EXPIRE (1UL << 1)
|
|
#define GQSPI_IXR_TX_FIFO_NOT_FULL (1UL << 2)
|
|
#define GQSPI_IXR_TX_FIFO_FULL (1UL << 3)
|
|
#define GQSPI_IXR_RX_FIFO_NOT_EMPTY (1UL << 4)
|
|
#define GQSPI_IXR_RX_FIFO_FULL (1UL << 5)
|
|
#define GQSPI_IXR_GEN_FIFO_EMPTY (1UL << 7)
|
|
#define GQSPI_IXR_TX_FIFO_EMPTY (1UL << 8)
|
|
#define GQSPI_IXR_GEN_FIFO_NOT_FULL (1UL << 9)
|
|
#define GQSPI_IXR_GEN_FIFO_FULL (1UL << 10)
|
|
#define GQSPI_IXR_RX_FIFO_EMPTY (1UL << 11)
|
|
#define GQSPI_IXR_ALL_MASK 0x0FBEU
|
|
#define GQSPI_ISR_WR_TO_CLR_MASK 0x02U
|
|
|
|
/* GenFIFO Entry bits */
|
|
#define GQSPI_GEN_FIFO_IMM_MASK 0xFFU
|
|
#define GQSPI_GEN_FIFO_IMM(x) ((x) & GQSPI_GEN_FIFO_IMM_MASK)
|
|
#define GQSPI_GEN_FIFO_DATA_XFER (1UL << 8)
|
|
#define GQSPI_GEN_FIFO_EXP (1UL << 9)
|
|
#define GQSPI_GEN_FIFO_MODE_SPI (1UL << 10)
|
|
#define GQSPI_GEN_FIFO_MODE_DSPI (2UL << 10)
|
|
#define GQSPI_GEN_FIFO_MODE_QSPI (3UL << 10)
|
|
#define GQSPI_GEN_FIFO_MODE_MASK (3UL << 10)
|
|
#define GQSPI_GEN_FIFO_CS_LOWER (1UL << 12)
|
|
#define GQSPI_GEN_FIFO_CS_UPPER (1UL << 13)
|
|
#define GQSPI_GEN_FIFO_CS_MASK (3UL << 12)
|
|
#define GQSPI_GEN_FIFO_CS_BOTH (3UL << 12)
|
|
#define GQSPI_GEN_FIFO_BUS_LOW (1UL << 14)
|
|
#define GQSPI_GEN_FIFO_BUS_UP (1UL << 15)
|
|
#define GQSPI_GEN_FIFO_BUS_BOTH (3UL << 14)
|
|
#define GQSPI_GEN_FIFO_BUS_MASK (3UL << 14)
|
|
#define GQSPI_GEN_FIFO_TX (1UL << 16)
|
|
#define GQSPI_GEN_FIFO_RX (1UL << 17)
|
|
#define GQSPI_GEN_FIFO_STRIPE (1UL << 18)
|
|
#define GQSPI_GEN_FIFO_POLL (1UL << 19)
|
|
|
|
/* DMA Control bits */
|
|
#define GQSPIDMA_CTRL_DEF 0x403FFA00UL
|
|
#define GQSPIDMA_CTRL2_DEF 0x081BFFF8UL
|
|
#define GQSPIDMA_CTRL_ENDIANNESS (1UL << 23)
|
|
|
|
/* DMA Status bits */
|
|
#define GQSPIDMA_STS_BUSY (1UL << 0)
|
|
#define GQSPIDMA_STS_WTC (7UL << 13)
|
|
|
|
/* DMA Interrupt bits */
|
|
#define GQSPIDMA_ISR_DONE (1UL << 1)
|
|
#define GQSPIDMA_ISR_ALL_MASK 0xFEU
|
|
|
|
/* FIFO Control bits */
|
|
#define GQSPI_FIFO_CTRL_RST_GEN (1UL << 0)
|
|
#define GQSPI_FIFO_CTRL_RST_TX (1UL << 1)
|
|
#define GQSPI_FIFO_CTRL_RST_RX (1UL << 2)
|
|
|
|
/* QSPI Select */
|
|
#define GQSPI_SEL_GQSPI (1UL << 0)
|
|
|
|
/* Flash Commands */
|
|
#define FLASH_CMD_READ_ID 0x9F
|
|
#define FLASH_CMD_READ_STATUS 0x05
|
|
#define FLASH_CMD_READ_FLAG_STATUS 0x70
|
|
#define FLASH_CMD_WRITE_ENABLE 0x06
|
|
#define FLASH_CMD_WRITE_DISABLE 0x04
|
|
#define FLASH_CMD_READ 0x03
|
|
#define FLASH_CMD_FAST_READ 0x0B
|
|
#define FLASH_CMD_QUAD_READ 0x6B
|
|
#define FLASH_CMD_READ_4B 0x13
|
|
#define FLASH_CMD_FAST_READ_4B 0x0C
|
|
#define FLASH_CMD_QUAD_READ_4B 0x6C
|
|
#define FLASH_CMD_PAGE_PROG 0x02
|
|
#define FLASH_CMD_PAGE_PROG_4B 0x12
|
|
#define FLASH_CMD_SECTOR_ERASE 0xD8
|
|
#define FLASH_CMD_SECTOR_ERASE_4B 0xDC
|
|
#define FLASH_CMD_ENTER_4B_MODE 0xB7
|
|
#define FLASH_CMD_EXIT_4B_MODE 0xE9
|
|
|
|
/* Flash Status Register bits */
|
|
#define FLASH_SR_WIP (1UL << 0) /* Write In Progress */
|
|
#define FLASH_SR_WEL (1UL << 1) /* Write Enable Latch */
|
|
#define FLASH_FSR_READY (1UL << 7) /* Flag Status Ready */
|
|
|
|
/* Flash Configuration for MT25QU01GBBB */
|
|
#define FLASH_JEDEC_MICRON 0x20
|
|
#define FLASH_JEDEC_MT25QU01G 0x20BB21
|
|
#define FLASH_PAGE_SIZE 256
|
|
#define FLASH_SECTOR_SIZE 0x10000 /* 64KB */
|
|
#define FLASH_DEVICE_SIZE 0x8000000 /* 128MB per chip */
|
|
|
|
/* Total flash size depends on single vs dual parallel configuration */
|
|
#if GQPI_USE_DUAL_PARALLEL == 1
|
|
#define FLASH_TOTAL_SIZE (FLASH_DEVICE_SIZE * 2) /* 256MB total */
|
|
#else
|
|
#define FLASH_TOTAL_SIZE FLASH_DEVICE_SIZE /* 128MB total */
|
|
#endif
|
|
|
|
/* QSPI Configuration (bare-metal driver) */
|
|
#ifndef GQSPI_CLK_REF
|
|
#define GQSPI_CLK_REF 300000000 /* 300 MHz */
|
|
#endif
|
|
#ifndef GQSPI_CLK_DIV
|
|
#define GQSPI_CLK_DIV 1 /* Formula: 300MHz / (2 << 1) = 75MHz */
|
|
#endif
|
|
#define GQSPI_CS_ASSERT_CLOCKS 5 /* CS Setup Time (tCSS) */
|
|
#define GQSPI_CS_DEASSERT_CLOCKS 4 /* CS Hold Time */
|
|
#define GQSPI_FIFO_WORD_SZ 4
|
|
#define GQSPI_DMA_ALIGN 64 /* L1 cache size */
|
|
#ifndef GQSPI_DMA_TMPSZ
|
|
#define GQSPI_DMA_TMPSZ 4096
|
|
#endif
|
|
#define GQSPI_TIMEOUT_TRIES 100000
|
|
#define GQSPIDMA_TIMEOUT_TRIES 100000000
|
|
#define GQSPI_FLASH_READY_TRIES 1000000 /* Erase can take seconds */
|
|
|
|
/* QSPI Mode Configuration */
|
|
#ifndef GQSPI_QSPI_MODE
|
|
#define GQSPI_QSPI_MODE GQSPI_GEN_FIFO_MODE_QSPI /* 4-bit data */
|
|
#endif
|
|
#ifndef GQPI_USE_DUAL_PARALLEL
|
|
#define GQPI_USE_DUAL_PARALLEL 1 /* 0=single, 1=dual parallel (striped) */
|
|
#endif
|
|
#ifndef GQPI_USE_4BYTE_ADDR
|
|
#define GQPI_USE_4BYTE_ADDR 1 /* 0=3-byte addr, 1=4-byte addr */
|
|
#endif
|
|
#ifndef GQSPI_DUMMY_READ
|
|
#define GQSPI_DUMMY_READ 8 /* Dummy clocks for Fast/Quad Read */
|
|
#endif
|
|
|
|
#ifndef XALIGNED
|
|
#define XALIGNED(x) __attribute__((aligned(x)))
|
|
#endif
|
|
|
|
|
|
/* ============================================================================
|
|
* SD/eMMC Controller (SDHCI)
|
|
* ============================================================================
|
|
* Versal has 2 SD/eMMC controllers
|
|
*/
|
|
#define VERSAL_SD0_BASE 0xF1040000UL
|
|
#define VERSAL_SD1_BASE 0xF1050000UL
|
|
|
|
|
|
/* ============================================================================
|
|
* Helper Functions (C code only)
|
|
* ============================================================================
|
|
*/
|
|
#ifndef __ASSEMBLER__
|
|
|
|
/* Get current exception level */
|
|
static inline unsigned int current_el(void)
|
|
{
|
|
unsigned long el;
|
|
__asm__ volatile("mrs %0, CurrentEL" : "=r" (el));
|
|
return (unsigned int)((el >> 2) & 0x3);
|
|
}
|
|
|
|
/* Memory barrier */
|
|
static inline void dmb(void)
|
|
{
|
|
__asm__ volatile("dmb sy" ::: "memory");
|
|
}
|
|
|
|
static inline void dsb(void)
|
|
{
|
|
__asm__ volatile("dsb sy" ::: "memory");
|
|
}
|
|
|
|
static inline void isb(void)
|
|
{
|
|
__asm__ volatile("isb" ::: "memory");
|
|
}
|
|
|
|
#endif /* __ASSEMBLER__ */
|
|
|
|
#endif /* _VERSAL_H_ */
|
|
|