Files
sw_openocd/contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h
Ryan QIAN 8e11797618 contrib/loaders/flash/hpmicro: add hpmicro device xpi support
- add xpi flash support for hpmicro devices

Change-Id: I3531fdf20a34561c6f3fe6ac0b9af988d483aae7
Signed-off-by: Ryan QIAN <jianghao.qian@hpmicro.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8695
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
2025-12-19 21:16:27 +00:00

255 lines
9.3 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Copyright (c) 2021 HPMicro
*/
#ifndef HPM_ROMAPI_XPI_DEF_H
#define HPM_ROMAPI_XPI_DEF_H
/**
* @brief XPI ROM APIs
* @defgroup xpi_interface XPI driver APIs
* @{
*/
#include "hpm_common.h"
/**
* @brief XPI Read Sample Clock source options
*/
enum xpi_rxclksrc_type_t {
xpi_rxclksrc_internal_loopback = 0, /**< Internal loopback */
xpi_rxclksrc_dqs_loopback = 1, /**< Loopback from DQS pad */
xpi_rxclksrc_external_dqs = 3, /**< Read is driven by External DQS pad */
};
/**
* @brief XPI pad definitions
*/
#define XPI_1PAD (0U) /**< Single pad */
#define XPI_2PADS (1U) /**< Dual pads */
#define XPI_4PADS (2U) /**< Quad pads */
#define XPI_8PADS (3U) /**< Octal pads */
/**
* @brief XPI IO pin group options
*/
enum xpi_io_group_t {
xpi_io_1st_group, /**< First/Primary group */
xpi_io_2nd_group, /**< Second/Secondary group */
};
/**
* @brief XPI Transfer Channel type definitions
*/
enum xpi_xfer_channel_t {
xpi_xfer_channel_a1, /**< The address is based on the device connected to Channel A1 */
xpi_xfer_channel_a2, /**< The address is based on the device connected to Channel A2 */
xpi_xfer_channel_b1, /**< The address is based on the device connected to Channel B1 */
xpi_xfer_channel_b2, /**< The address is based on the device connected to Channel B2 */
xpi_xfer_channel_auto, /**< The channel is auto determined */
};
/**
* @brief XPI Channel definitions
*/
enum xpi_channel_t {
xpi_channel_a1, /**< Port: Channel A1 */
xpi_channel_a2, /**< Port: Channel A2 */
xpi_channel_b1, /**< Port: Channel B1 */
xpi_channel_b2, /**< Port: Channel B2 */
};
/**
* @brief XPI APB Transfer type
*/
enum xpi_apb_xfer_type_t {
xpi_apb_xfer_type_cmd, /**< APB Command Type: Command only */
xpi_apb_xfer_type_config, /**< APB Command Type: Configuration */
xpi_apb_xfer_type_read, /**< APB Command Type: Read */
xpi_apb_xfer_type_write, /**< APB Command Type: Write */
};
/**
* @brief XPI Xfer Mode
*/
enum xpi_xfer_mode_t {
xpi_xfer_mode_polling, /**< Transfer mode: Polling */
xpi_xfer_mode_dma, /**< Transfer mode: DMA */
xpi_xfer_mode_interrupt, /**< Transfer mode: Interrupt */
};
/**
* @brief XPI Xfer context
*/
struct xpi_xfer_ctx_t {
uint32_t addr; /**< device address for XPI transfer */
uint8_t channel; /**< channel for XPI transfer */
uint8_t cmd_type; /**< command type for XPI transfer */
uint8_t seq_idx; /**< Sequence index for XPI transfer */
uint8_t seq_num; /**< Sequence number for XPI transfer */
uint32_t *buf; /**< Buffer for XPI transfer */
uint32_t xfer_size; /**< Transfer size in bytes */
};
/**
* @brief XPI instruction sequence
*/
struct xpi_instr_seq_t {
uint32_t entry[4];
};
/**
* @brief XPI Phase definitions
*/
#define XPI_PHASE_STOP (0x00U) /**< Phase: Stop */
#define XPI_PHASE_CMD_SDR (0x01U) /**< Phase: Send CMD in SDR mode */
#define XPI_PHASE_RADDR_SDR (0x02U) /**< Phase: Send Row Address in SDR Mode */
#define XPI_PHASE_CADDR_SDR (0x03U) /**< Phase: Send Column Address in SDR Mode */
#define XPI_PHASE_MODE4_SDR (0x06U) /**< Phase: Send Mode 4 in SDR Mode */
#define XPI_PHASE_MODE8_SDR (0x07U) /**< Phase: Send Mode 8 in SDR Mode */
#define XPI_PHASE_WRITE_SDR (0x08U) /**< Phase: Write data in SDR Mode */
#define XPI_PHASE_READ_SDR (0x09U) /**< Phase: Read data in SDR Mode */
#define XPI_PHASE_DUMMY_SDR (0X0CU) /**< Phase: Send Dummy in SDR Mode */
#define XPI_PHASE_DUMMY_RWDS_SDR (0x0DU) /**< Phase: Send Dummy RWDS in SDR Mode */
#define XPI_PHASE_CMD_DDR (0x21U) /**< Phase: Send CMD in DDR Mode */
#define XPI_PHASE_RADDR_DDR (0x22U) /**< Phase: Send Raw Address in DDR Mode */
#define XPI_PHASE_CADDR_DDR (0x23U) /**< Phase: Send Column address in DDR Mode */
#define XPI_PHASE_MODE4_DDR (0x26U) /**< Phase: Send Mode 4 in DDR Mode */
#define XPI_PHASE_MODE8_DDR (0x27U) /**< Phase: Send Mode 8 in DDR Mode */
#define XPI_PHASE_WRITE_DDR (0x28U) /**< Phase: Write data in DDR Mode */
#define XPI_PHASE_READ_DDR (0x29U) /**< Phase: Read data in SDR Mode */
#define XPI_PHASE_DUMMY_DDR (0x2CU) /**< Phase: Send DUMMY in DDR Mode */
#define XPI_PHASE_DUMMY_RWDS_DDR (0x2DU) /**< Phase: Send DUMMY RWDS in DDR Mode */
/**
* @brief XPI API command error codes
*/
enum {
status_xpi_apb_jump_on_cs = MAKE_STATUS(status_group_xpi, 1),
status_xpi_apb_unknown_inst = MAKE_STATUS(status_group_xpi, 2),
status_xpi_apb_dummy_sdr_in_ddr_seq = MAKE_STATUS(status_group_xpi, 3),
status_xpi_apb_dummy_ddr_in_sdr_seq = MAKE_STATUS(status_group_xpi, 4),
status_xpi_apb_exceed_addr_range = MAKE_STATUS(status_group_xpi, 5),
status_xpi_apb_seq_timeout = MAKE_STATUS(status_group_xpi, 6),
status_xpi_apb_cross_boundary = MAKE_STATUS(status_group_xpi, 7),
};
/**
* @brief Delay line definitions
*/
enum {
xpi_dll_half_cycle = 0xFU,
xpi_dll_quarter_cycle = 0x7U,
xpi_dll_sdr_default_cycle = xpi_dll_half_cycle,
xpi_dll_ddr_default_cycle = xpi_dll_quarter_cycle,
};
/**
* @brief XPI configuration structure
*/
struct xpi_config_t {
uint8_t rxclk_src; /**< Read sample clock source */
uint8_t reserved0[7]; /**< Reserved */
uint8_t tx_watermark_in_dwords; /**< Tx watermark in double words */
uint8_t rx_watermark_in_dwords; /**< Rx watermark in double words */
uint8_t enable_differential_clk; /**< Enable differential clock */
uint8_t reserved1[5]; /**< Reserved */
uint32_t access_flags; /**< Access flags */
};
/**
* @brief XPI Device Configuration structure
*/
struct xpi_device_config_t {
uint32_t size_in_kbytes; /**< Device size in kbytes */
uint32_t serial_root_clk_freq; /**< XPI serial root clock frequency */
uint8_t enable_write_mask; /**< Enable write mask, typically for PSRAM/HyperRAM */
uint8_t data_valid_time; /**< Data valid time, Unit 0.1ns */
uint8_t reserved0[2];
uint8_t cs_hold_time; /**< CS hold time, cycles in terms of FLASH clock */
uint8_t cs_setup_time; /**< CS setup time, cycles in terms of FLASH clock */
uint16_t cs_interval; /**< CS interval, cycles in terms of FLASH clock */
uint8_t reserved1;
uint8_t column_addr_size; /**< Column address bits */
uint8_t enable_word_address; /**< Enable word address, for HyperFLASH/HyperRAM */
uint8_t dly_target; /**< Delay target */
uint8_t ahb_write_seq_idx; /**< AHB write sequence index */
uint8_t ahb_write_seq_num; /**< AHB write sequence number */
uint8_t ahb_read_seq_idx; /**< AHB read sequence index */
uint8_t ahb_read_seq_num; /**< AHB read sequence number */
uint8_t ahb_write_wait_interval; /**< AHB write wait interval, in terms of FLASH clock */
uint8_t reserved2[3];
};
/**
* @brief SUB Instruction
* @param [in] phase Name
* @param [in] pad Pad for Phase
* @param [in] op Operand for Phase
*/
#define SUB_INSTR(phase, pad, op) ((uint32_t)(((uint16_t)(phase) << 10) | ((uint16_t)(pad) << 8) | ((uint16_t)(op))))
/**
* @brief Generate a single word INSTRUCTION sequence word
* @note Here intentionally use the MACRO because when the arguments are constant value, the compiler
* can generate the const entry word during pre-processing
*/
#define XPI_INSTR_SEQ(phase0, pad0, op0, phase1, pad1, op1) \
(SUB_INSTR(phase0, pad0, op0) | (SUB_INSTR(phase1, pad1, op1) << 16))
struct xpi_ahb_buffer_cfg_t {
struct {
uint8_t priority; /* Offset: 0x00 */
uint8_t master_idx; /* Offset: 0x01 */
uint8_t buf_size_in_dword; /* Offset: 0x02 */
bool enable_prefetch; /* Offset: 0x03 */
} entry[8];
};
/**
* @brief XPI driver interface
*/
struct xpi_driver_interface_t {
/**< XPI driver interface: version */
uint32_t version;
/**< XPI driver interface: get default configuration */
hpm_stat_t (*get_default_config)(struct xpi_config_t *xpi_config);
/**< XPI driver interface: get default device configuration */
hpm_stat_t (*get_default_device_config)(struct xpi_device_config_t *dev_config);
/**< XPI driver interface: initialize the XPI using xpi_config */
hpm_stat_t (*init)(uint32_t *base, struct xpi_config_t *xpi_config);
/**< XPI driver interface: configure the AHB buffer */
hpm_stat_t (*config_ahb_buffer)(uint32_t *base, struct xpi_ahb_buffer_cfg_t *ahb_buf_cfg);
/**< XPI driver interface: configure the device */
hpm_stat_t (*config_device)(uint32_t *base, struct xpi_device_config_t *dev_cfg, enum xpi_channel_t channel);
/**< XPI driver interface: update instruction talbe */
hpm_stat_t (*update_instr_table)(uint32_t *base, const uint32_t *inst_base, uint32_t seq_idx, uint32_t num);
/**< XPI driver interface: transfer command/data using block interface */
hpm_stat_t (*transfer_blocking)(uint32_t *base, struct xpi_xfer_ctx_t *xfer);
/**< Software reset the XPI controller */
void (*software_reset)(uint32_t *base);
/**< XPI driver interface: Check whether IP is idle */
bool (*is_idle)(uint32_t *base);
/**< XPI driver interface: update delay line setting */
void (*update_dllcr)(uint32_t *base,
uint32_t serial_root_clk_freq,
uint32_t data_valid_time,
enum xpi_channel_t channel,
uint32_t dly_target);
/**< XPI driver interface: Get absolute address for APB transfer */
hpm_stat_t
(*get_abs_apb_xfer_addr)(uint32_t *base, enum xpi_xfer_channel_t channel, uint32_t in_addr, uint32_t *out_addr);
};
/**
* @}
*/
#endif /* HPM_ROMAPI_XPI_DEF_H */