forked from auracaster/openocd
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>
This commit is contained in:
51
contrib/loaders/flash/hpmicro/Makefile
Normal file
51
contrib/loaders/flash/hpmicro/Makefile
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
# Copyright (c) 2023 HPMicro
|
||||||
|
#
|
||||||
|
BIN2C = ../../../../src/helper/bin2char.sh
|
||||||
|
|
||||||
|
|
||||||
|
PROJECT=hpm_xpi_flash
|
||||||
|
CROSS_COMPILE ?= riscv32-unknown-elf-
|
||||||
|
CC=$(CROSS_COMPILE)gcc
|
||||||
|
AS=$(CROSS_COMPILE)gcc
|
||||||
|
OBJCOPY=$(CROSS_COMPILE)objcopy
|
||||||
|
OBJDUMP=$(CROSS_COMPILE)objdump
|
||||||
|
LD=$(CROSS_COMPILE)ld
|
||||||
|
LDSCRIPT=linker.ld
|
||||||
|
|
||||||
|
OPT=-O3
|
||||||
|
|
||||||
|
ASFLAGS=
|
||||||
|
CFLAGS=$(OPT) -fomit-frame-pointer -Wall
|
||||||
|
LDFLAGS=-nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map -static -Wl,--gc-sections
|
||||||
|
OBJS=$(ASRC:.S=.o) $(SRC:.c=.o)
|
||||||
|
|
||||||
|
SRC=openocd_flash_algo.c
|
||||||
|
ASRC=func_table.S
|
||||||
|
|
||||||
|
all: $(OBJS) $(PROJECT).elf $(PROJECT).bin $(PROJECT).lst $(PROJECT).inc
|
||||||
|
|
||||||
|
%o: %c
|
||||||
|
@$(CC) -c $(CFLAGS) -I . $< -o $@
|
||||||
|
|
||||||
|
%o: %S
|
||||||
|
@$(AS) -c $(ASFLAGS) -I . $< -o $@
|
||||||
|
|
||||||
|
%elf: $(OBJS)
|
||||||
|
@$(CC) $(OBJS) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
%lst: %elf
|
||||||
|
@$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
%bin: %elf
|
||||||
|
@$(OBJCOPY) -Obinary $< $@
|
||||||
|
|
||||||
|
%inc: %bin
|
||||||
|
$(BIN2C) < $< > $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@-rm -f *.o *.elf *.lst *.bin *.inc
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
.INTERMEDIATE: $(patsubst %.S,%.o,$(SRCS)) $(patsubst %.S,%.elf,$(SRCS)) $(patsubst %.S,%.bin,$(SRCS))
|
||||||
7
contrib/loaders/flash/hpmicro/README
Normal file
7
contrib/loaders/flash/hpmicro/README
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
The loader relies on the romapi provided by HPMicro devices.
|
||||||
|
|
||||||
|
- hpm_common.h and all the hpm_romapi_*.c/h are reused from hpm_sdk
|
||||||
|
(v1.9.0 https://github.com/hpmicro/hpm_sdk/releases).
|
||||||
|
|
||||||
|
Due to different coding rules, these source code needs to be updated
|
||||||
|
accordingly to pass the coding rule check for openocd.
|
||||||
21
contrib/loaders/flash/hpmicro/func_table.S
Normal file
21
contrib/loaders/flash/hpmicro/func_table.S
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 HPMicro
|
||||||
|
*/
|
||||||
|
.section .func_table, "ax"
|
||||||
|
.global _init
|
||||||
|
_init:
|
||||||
|
jal flash_init
|
||||||
|
ebreak
|
||||||
|
jal flash_erase
|
||||||
|
ebreak
|
||||||
|
jal flash_program
|
||||||
|
ebreak
|
||||||
|
jal flash_read
|
||||||
|
ebreak
|
||||||
|
jal flash_get_info
|
||||||
|
ebreak
|
||||||
|
jal flash_erase_chip
|
||||||
|
ebreak
|
||||||
|
jal flash_deinit
|
||||||
|
ebreak
|
||||||
203
contrib/loaders/flash/hpmicro/hpm_common.h
Normal file
203
contrib/loaders/flash/hpmicro/hpm_common.h
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021-2023 HPMicro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HPM_COMMON_H
|
||||||
|
#define _HPM_COMMON_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief COMMON driver APIs
|
||||||
|
* @defgroup common_interface COMMON driver APIs
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __R volatile const /* Define "read-only" permission */
|
||||||
|
#define __RW volatile /* Define "read-write" permission */
|
||||||
|
#define __W volatile /* Define "write-only" permission */
|
||||||
|
|
||||||
|
#ifndef __I
|
||||||
|
#define __I __R
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IO
|
||||||
|
#define __IO __RW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __O
|
||||||
|
#define __O __W
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
|
||||||
|
#define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 0U)
|
||||||
|
#define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 0U)
|
||||||
|
#define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 0U)
|
||||||
|
#define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 0U)
|
||||||
|
|
||||||
|
#define HPM_BREAK_IF(cond) do {if (cond) break; } while (0)
|
||||||
|
#define HPM_CONTINUE_IF(cond) do {if (cond) continue; } while (0)
|
||||||
|
|
||||||
|
#define HPM_CHECK_RET(x) \
|
||||||
|
do { \
|
||||||
|
stat = (x); \
|
||||||
|
if (status_success != stat) { \
|
||||||
|
return stat; \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#define SIZE_1KB (1024UL)
|
||||||
|
#define SIZE_1MB (1048576UL)
|
||||||
|
|
||||||
|
typedef uint32_t hpm_stat_t;
|
||||||
|
|
||||||
|
/* @brief Enum definition for the Status group
|
||||||
|
* Rule:
|
||||||
|
* [Group] 0-999 for the SoC driver and the corresponding components
|
||||||
|
* 1000 or above for the application status group
|
||||||
|
* [Code] Valid value: 0-999
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define MAKE_STATUS(group, code) ((uint32_t)(group) * 1000U + (uint32_t)(code))
|
||||||
|
/* @brief System status group definitions */
|
||||||
|
enum {
|
||||||
|
status_group_common = 0,
|
||||||
|
status_group_uart = 1,
|
||||||
|
status_group_i2c = 2,
|
||||||
|
status_group_spi = 3,
|
||||||
|
status_group_usb = 4,
|
||||||
|
status_group_i2s = 5,
|
||||||
|
status_group_xpi = 6,
|
||||||
|
status_group_l1c,
|
||||||
|
status_group_dma,
|
||||||
|
status_group_femc,
|
||||||
|
status_group_sdp,
|
||||||
|
status_group_xpi_nor,
|
||||||
|
status_group_otp,
|
||||||
|
status_group_lcdc,
|
||||||
|
status_group_mbx,
|
||||||
|
status_group_rng,
|
||||||
|
status_group_pdma,
|
||||||
|
status_group_wdg,
|
||||||
|
status_group_pmic_sec,
|
||||||
|
status_group_can,
|
||||||
|
status_group_sdxc,
|
||||||
|
status_group_pcfg,
|
||||||
|
status_group_clk,
|
||||||
|
status_group_pllctl,
|
||||||
|
status_group_pllctlv2,
|
||||||
|
status_group_ffa,
|
||||||
|
status_group_mcan,
|
||||||
|
|
||||||
|
status_group_middleware_start = 500,
|
||||||
|
status_group_sdmmc = status_group_middleware_start,
|
||||||
|
status_group_audio_codec,
|
||||||
|
status_group_dma_manager,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* @brief Common status code definitions */
|
||||||
|
enum {
|
||||||
|
status_success = MAKE_STATUS(status_group_common, 0),
|
||||||
|
status_fail = MAKE_STATUS(status_group_common, 1),
|
||||||
|
status_invalid_argument = MAKE_STATUS(status_group_common, 2),
|
||||||
|
status_timeout = MAKE_STATUS(status_group_common, 3),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
|
/* alway_inline */
|
||||||
|
#define ATTR_ALWAYS_INLINE __attribute__((always_inline))
|
||||||
|
|
||||||
|
/* weak */
|
||||||
|
#define ATTR_WEAK __attribute__((weak))
|
||||||
|
|
||||||
|
/* alignment */
|
||||||
|
#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
|
||||||
|
|
||||||
|
/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
|
||||||
|
#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
|
||||||
|
ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
|
||||||
|
#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_RAMFUNC ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
|
||||||
|
|
||||||
|
#define NOP() __asm volatile("nop")
|
||||||
|
#define WFI() __asm volatile("wfi")
|
||||||
|
|
||||||
|
#define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)))
|
||||||
|
|
||||||
|
#elif defined(__ICCRISCV__)
|
||||||
|
|
||||||
|
/* alway_inline */
|
||||||
|
#define ATTR_ALWAYS_INLINE __attribute__((always_inline))
|
||||||
|
|
||||||
|
/* weak */
|
||||||
|
#define ATTR_WEAK __weak
|
||||||
|
|
||||||
|
/* alignment */
|
||||||
|
#define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
|
||||||
|
|
||||||
|
/* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
|
||||||
|
#define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
|
||||||
|
ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable.bss")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
/* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
|
||||||
|
#define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
|
||||||
|
#define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
|
||||||
|
ATTR_RAMFUNC ATTR_ALIGN(alignment)
|
||||||
|
|
||||||
|
#define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
|
||||||
|
|
||||||
|
#define NOP() __asm volatile("nop")
|
||||||
|
#define WFI() __asm volatile("wfi")
|
||||||
|
|
||||||
|
#define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown toolchain
|
||||||
|
#endif
|
||||||
|
#endif /* _HPM_COMMON_H */
|
||||||
52
contrib/loaders/flash/hpmicro/hpm_romapi.h
Normal file
52
contrib/loaders/flash/hpmicro/hpm_romapi.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021-2023 HPMicro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HPM_ROMAPI_H
|
||||||
|
#define HPM_ROMAPI_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ROM APIs
|
||||||
|
* @defgroup romapi_interface ROM APIs
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hpm_common.h"
|
||||||
|
#include "hpm_romapi_xpi_def.h"
|
||||||
|
#include "hpm_romapi_xpi_soc_def.h"
|
||||||
|
#include "hpm_romapi_xpi_nor_def.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Definitions
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bootloader API table
|
||||||
|
*/
|
||||||
|
struct bootloader_api_table_t {
|
||||||
|
/**< Bootloader API table: version */
|
||||||
|
const uint32_t version;
|
||||||
|
/**< Bootloader API table: copyright string address */
|
||||||
|
const char *copyright;
|
||||||
|
/**< Bootloader API table: run_bootloader API */
|
||||||
|
const uint32_t reserved0;
|
||||||
|
/**< Bootloader API table: otp driver interface address */
|
||||||
|
const uint32_t reserved1;
|
||||||
|
/**< Bootloader API table: xpi driver interface address */
|
||||||
|
const struct xpi_driver_interface_t *xpi_driver_if;
|
||||||
|
/**< Bootloader API table: xpi nor driver interface address */
|
||||||
|
const struct xpi_nor_driver_interface_t *xpi_nor_driver_if;
|
||||||
|
/**< Bootloader API table: xpi ram driver interface address */
|
||||||
|
const uint32_t reserved2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**< Bootloader API table Root */
|
||||||
|
#define ROM_API_TABLE_ROOT ((const struct bootloader_api_table_t *)0x2001FF00U)
|
||||||
|
|
||||||
|
#endif /* HPM_ROMAPI_H */
|
||||||
254
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h
Normal file
254
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_def.h
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/* 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 */
|
||||||
426
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h
Normal file
426
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_nor_def.h
Normal file
@@ -0,0 +1,426 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 HPMicro
|
||||||
|
*/
|
||||||
|
#ifndef HPM_ROMAPI_XPI_NOR_DEF_H
|
||||||
|
#define HPM_ROMAPI_XPI_NOR_DEF_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR ROM APIs
|
||||||
|
* @defgroup xpi_nor_interface XPI NOR driver APIs
|
||||||
|
* @ingroup romapi_interfaces
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hpm_common.h"
|
||||||
|
#include "hpm_romapi_xpi_def.h"
|
||||||
|
|
||||||
|
#define XPI_NOR_CFG_TAG 0x524f4E58U /**< ASCII: "XNOR" */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR properties
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
xpi_nor_property_total_size, /**< Total size in bytes */
|
||||||
|
xpi_nor_property_page_size, /**< Page size in bytes */
|
||||||
|
xpi_nor_property_sector_size, /**<sector size in bytes */
|
||||||
|
xpi_nor_property_block_size, /**< block size in bytes */
|
||||||
|
xpi_nor_property_max = xpi_nor_property_block_size,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR safe frequency option
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
xpi_nor_clk_safe_clk_freq = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR miscellaneous options
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
xpi_nor_option_misc_spi_only = 1, /**< SPI only */
|
||||||
|
xpi_nor_option_misc_internal_loopback = 2, /**< Internal loopback mode */
|
||||||
|
xpi_nor_option_misc_ext_dqs = 3, /**< External DQS pin */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR connection option
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
xpi_nor_connection_sel_chna_cs0, /**< Channel A, CS0 */
|
||||||
|
xpi_nor_connection_sel_chnb_cs0, /**< Channel B, CS0 */
|
||||||
|
xpi_nor_connection_sel_chna_cs0_chnb_cs0, /**< Channel A + Channel B, CS0 */
|
||||||
|
xpi_nor_connection_sel_chna_cs0_cs1, /**< Channel A, CS0 + CS1 */
|
||||||
|
xpi_nor_connection_sel_chnb_cs0_cs1 /**< Channel B, CS0 + CS1 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QE bit enable sequence option
|
||||||
|
*/
|
||||||
|
enum xpi_nor_quad_enable_seq_t {
|
||||||
|
xpi_nor_quad_en_auto_or_ignore = 0U, /**< Auto enable or ignore */
|
||||||
|
xpi_nor_quad_en_set_bit6_in_status_reg1 = 1U, /**< QE bit is at bit6 in Status register 1 */
|
||||||
|
xpi_nor_quad_en_set_bit1_in_status_reg2 = 2U, /**< QE bit is at bit1 in Status register 2 register 2 */
|
||||||
|
xpi_nor_quad_en_set_bit7_in_status_reg2 = 3U, /**< QE bit is at bit7 in Status register 2 */
|
||||||
|
xpi_nor_quad_en_set_bi1_in_status_reg2_via_0x31_cmd = 4U, /**< QE bit is in status register 2 via CMD 0x31 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI working mode
|
||||||
|
*/
|
||||||
|
enum xpi_working_mode_t {
|
||||||
|
xpi_working_mode_extend_spi, /**< XPI works in extended SPI mode, including 1-1-1, 1-2-2, 1-4-4, 1-8-8 */
|
||||||
|
xpi_working_mode_xpi, /**< XPI works in XPI mode, including, 1-1-1, 2-2-2, 4-4-4, 8-8-8 */
|
||||||
|
xpi_working_mode_hyperbus, /**< XPI works in HyperBus mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR configuration command type
|
||||||
|
*/
|
||||||
|
enum xpi_nor_cfg_cmd_type_t {
|
||||||
|
xpi_nor_cfg_cmd_type_no_cfg = 0U, /**< No configuration */
|
||||||
|
xpi_nor_cfg_cmd_type_generic = 1U, /**< Generic configuration */
|
||||||
|
xpi_nor_cfg_cmd_type_spi2xpi = 2U, /**< SPI to XPI mode */
|
||||||
|
xpi_nor_cfg_cmd_type_xpi2spi = 3U, /**< XPI to SPI mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR probe options
|
||||||
|
*/
|
||||||
|
enum xpi_nor_probe_t {
|
||||||
|
xpi_nor_probe_sfdp_sdr = 0U, /**< Probe FLASH using SFDP and set FLASH to SDR mode */
|
||||||
|
xpi_nor_probe_sfdp_ddr = 1U, /**< Probe FLASH using SDP and set FLASH to DDR mode */
|
||||||
|
xpi_nor_quad_read_0xeb = 2U, /**< Set FLASH to default Quad I/O read in SDR mode */
|
||||||
|
xpi_nor_dual_read_0xbb = 3U, /**< Set FLASH to default Dual I/O read in SDR mode */
|
||||||
|
xpi_nor_hyperbus_1v8 = 4U, /**< Probe FLASH using HyperBus in 1.8V voltage */
|
||||||
|
xpi_nor_hyperbus_3v0 = 5U, /**< Probe FLASH using HyperBus in 3.0V voltage */
|
||||||
|
xpi_nor_octabus_ddr = 6U, /**< Probe FLASH using Macronix OctaBus and configure FLASH to OPI DDR mode */
|
||||||
|
xpi_nor_octabus_sdr = 7U, /**< Probe FLASH using Macronix OctaBus and configure FLASH to OPI SDR mode */
|
||||||
|
xpi_nor_xccela_ddr = 8U, /**< Probe FLASH using Xccela Protocol and configure FLASH to OPI DDR mode */
|
||||||
|
xpi_nor_xccela_sdr = 9U, /**< Probe FLASH using Xccela Protocol and configure FLASH to SDR mode */
|
||||||
|
xpi_nor_ecoxip_ddr = 10U, /**< Probe FLASH using EcoXiP Protocol and configure FLASH to OPI DDR mode */
|
||||||
|
xpi_nor_ecoxip_sdr = 11U, /**< Probe FLASH using EcoXiP Protocol and configure FLASH to SDR mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Standard XPI NOR seuqnce index definitions
|
||||||
|
*/
|
||||||
|
enum xpi_std_nor_instr_idx_t {
|
||||||
|
xpi_std_nor_seq_idx_read = 0U, /**< 0 - Read */
|
||||||
|
xpi_std_nor_seq_idx_page_program = 1U, /**< 1 - Page Program */
|
||||||
|
xpi_std_nor_seq_idx_read_status = 2U, /**< 2 - Read Status */
|
||||||
|
xpi_std_nor_seq_idx_read_status_xpi = 3U, /**< 3 - Read Status in xSPI mode */
|
||||||
|
xpi_std_nor_seq_idx_write_enable = 4U, /**< 4 - Write Enable */
|
||||||
|
xpi_std_nor_seq_idx_write_enable_xpi = 5U, /**< 5 - Write Enable in xSPI mode */
|
||||||
|
xpi_std_nor_seq_idx_erase_sector = 6U, /**< 6 - Erase sector */
|
||||||
|
xpi_std_nor_seq_idx_erase_block = 7U, /**< 7 - Erase block */
|
||||||
|
xpi_std_nor_seq_idx_erase_chip = 8U, /**< 8 - Erase full chip */
|
||||||
|
xpi_std_nor_seq_idx_max = 9, /**< 9 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR option tag
|
||||||
|
*/
|
||||||
|
#define XPI_NOR_CFG_OPTION_TAG (0xfcf90U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR configuration option
|
||||||
|
* The ROM SW can detect the FLASH configuration based on the following structure specified by the end-user
|
||||||
|
*/
|
||||||
|
struct xpi_nor_config_option_t {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t words: 4; /**< Option words, exclude the header itself */
|
||||||
|
uint32_t reserved: 8; /**< Reserved for future use */
|
||||||
|
uint32_t tag: 20; /**< Must be 0xfcf90 */
|
||||||
|
};
|
||||||
|
uint32_t U;
|
||||||
|
} header;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t freq_opt: 4; /**< 1 - 30MHz, others, SoC specific setting */
|
||||||
|
uint32_t misc: 4; /**< Not used for now */
|
||||||
|
uint32_t dummy_cycles: 8; /**< 0 - Auto detected/ use predefined value, others: by end-user */
|
||||||
|
uint32_t quad_enable_seq: 4; /**< See the xpi_nor_quad_enable_seq_t definitions for more details */
|
||||||
|
uint32_t cmd_pads_after_init: 4; /**< See the xpi_data_pad_t definitions for more details */
|
||||||
|
uint32_t cmd_pads_after_por: 4; /**< See the xpi_data_pad_t definitions for more details */
|
||||||
|
uint32_t probe_type: 4; /**< See the xpi_nor_probe_t definitions for more details */
|
||||||
|
};
|
||||||
|
uint32_t U;
|
||||||
|
} option0;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t drive_strength: 8; /**< IO drive strength, 0 - pre-defined, Others - specified by end-user */
|
||||||
|
uint32_t connection_sel: 4; /**< Device connection selection: 0 - PORTA, 1 - PORTB, 2 - Parallel mode */
|
||||||
|
uint32_t pin_group_sel: 4; /**< Pin group selection, 0 - 1st group, 1 - 2nd group, default, 1st group */
|
||||||
|
uint32_t io_voltage: 4; /**< SoC pad voltage, 0 - 3.0V, 1-1.8V */
|
||||||
|
uint32_t reserved: 12; /**< Reserved for future use */
|
||||||
|
};
|
||||||
|
uint32_t U;
|
||||||
|
} option1;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t flash_size_option:8; /**< FLASH size option */
|
||||||
|
uint32_t flash_sector_size_option:4; /**< FLASH sector size option */
|
||||||
|
uint32_t flash_sector_erase_cmd_option:4; /**< Sector Erase command option */
|
||||||
|
uint32_t reserved:20;
|
||||||
|
};
|
||||||
|
uint32_t U;
|
||||||
|
} option2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sector size options
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
serial_nor_sector_size_4kb, /**< Sector size: 4KB */
|
||||||
|
serial_nor_sector_size_32kb, /**< Sector size: 32KB */
|
||||||
|
serial_nor_sector_size_64kb, /**< Sector size: 64KB */
|
||||||
|
serial_nor_sector_size_256kb, /**< Sector size: 256KB */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sector erase command options
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
serial_nor_erase_type_4kb, /**< Sector erase command: 4KB Erase */
|
||||||
|
serial_nor_erase_type_32kb, /**< Sector erase command: 32KB Erase */
|
||||||
|
serial_nor_erase_type_64kb, /**< Sector erase command: 64KB Erase */
|
||||||
|
serial_nor_erase_type_256kb, /**< Sector erase command: 256KB Erase */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FLASH size options
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
flash_size_4mb, /**< FLASH size: 4MB */
|
||||||
|
flash_size_8mb, /**< FLASH size: 8MB */
|
||||||
|
flash_size_16mb, /**< FLASH size: 16MB */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Device Mode configuration structure
|
||||||
|
*/
|
||||||
|
struct device_mode_cfg_t {
|
||||||
|
uint8_t cfg_cmd_type; /**< Configuration command type */
|
||||||
|
uint8_t param_size; /**< Size for parameter */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Device mode parameter structure
|
||||||
|
*/
|
||||||
|
struct device_mode_param_t {
|
||||||
|
uint32_t instr_seq[4]; /**< Command Instruction sequence*/
|
||||||
|
uint32_t param; /**< Parameter */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR device information structure
|
||||||
|
*/
|
||||||
|
struct xpi_device_info_t {
|
||||||
|
uint32_t size_in_kbytes; /**< Device Size in Kilobytes, offset 0x00 */
|
||||||
|
uint16_t page_size; /**< Page size, offset 0x04 */
|
||||||
|
uint16_t sector_size_kbytes; /**< Sector size in kilobytes, offset 0x06 */
|
||||||
|
uint16_t block_size_kbytes; /**< Block size in kilobytes, offset 0x08 */
|
||||||
|
uint8_t busy_offset; /**< Busy offset, offset 0x0a */
|
||||||
|
uint8_t busy_polarity; /**< Busy polarity, offset 0x0b */
|
||||||
|
uint8_t data_pads; /**< Device Size in Kilobytes, offset 0x0c */
|
||||||
|
uint8_t en_ddr_mode; /**< Enable DDR mode, offset 0x0d */
|
||||||
|
uint8_t clk_freq_for_device_cfg; /**< Clk frequency for device configuration offset 0x0e */
|
||||||
|
uint8_t working_mode_por; /**< Working mode after POR reset offset 0x0f */
|
||||||
|
uint8_t working_mode; /**< The device working mode, offset 0x10 */
|
||||||
|
uint8_t en_diff_clk; /**< Enable Differential clock, offset 0x11 */
|
||||||
|
uint8_t data_valid_time; /**< Data valid time, in 0.1ns, offset 0x12 */
|
||||||
|
uint8_t en_half_clk_for_non_read_cmd; /**< Enable half clock for non-read command, offset 0x13 */
|
||||||
|
uint8_t clk_freq_for_non_read_cmd; /**< Enable safe clock for non-read command, offset 0x14 */
|
||||||
|
uint8_t dll_dly_target; /**< XPI DLL Delay Target, offset 0x15 */
|
||||||
|
uint8_t io_voltage; /**< IO voltage, offset 0x16 */
|
||||||
|
uint8_t reserved0; /**< Reserved for future use, offset 0x17 */
|
||||||
|
uint8_t cs_hold_time; /**< CS hold time, 0 - default, others - user specified, offset 0x18 */
|
||||||
|
uint8_t cs_setup_time; /**< CS setup time, 0 - default, others - user specified, offset 0x19 */
|
||||||
|
uint8_t cs_interval; /**< CS interval, intervals between to CS active, offset 0x1a */
|
||||||
|
uint8_t en_dev_mode_cfg; /**< Enable device mode configuration, offset 0x1b */
|
||||||
|
uint32_t flash_state_ctx; /**< Flash state context, offset 0x1c */
|
||||||
|
struct device_mode_cfg_t mode_cfg_list[2]; /**< Mode configuration sequences, offset 0x20 */
|
||||||
|
uint32_t mode_cfg_param[2]; /**< Mode configuration parameters, offset 0x24 */
|
||||||
|
uint32_t reserved1; /**< Reserved for future use, offset 0x2C */
|
||||||
|
struct {
|
||||||
|
uint32_t entry[4];
|
||||||
|
} cfg_instr_seq[2]; /**< Mode Configuration Instruction sequence, offset 0x30 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR configuration structure
|
||||||
|
*/
|
||||||
|
struct xpi_nor_config_t {
|
||||||
|
uint32_t tag; /**< Must be "XNOR", offset 0x000 */
|
||||||
|
uint32_t reserved0; /**< Reserved for future use, offset 0x004 */
|
||||||
|
uint8_t rxclk_src; /**< RXCLKSRC value, offset 0x008 */
|
||||||
|
uint8_t clk_freq; /**< Clock frequency, offset 0x009 */
|
||||||
|
uint8_t drive_strength; /**< Drive strength, offset 0x0a */
|
||||||
|
uint8_t column_addr_size; /**< Column address size, offset 0x0b */
|
||||||
|
uint8_t rxclk_src_for_init; /**< RXCLKSRC during FLASH initialization, offset 0x0c */
|
||||||
|
uint8_t config_in_progress; /**< Indicate whether device configuration is in progress, offset: 0x0d */
|
||||||
|
uint8_t reserved[2]; /**< Reserved for future use, offset 0x00f */
|
||||||
|
struct {
|
||||||
|
uint8_t enable; /**< Port enable flag, 0 - not enabled, 1 - enabled */
|
||||||
|
uint8_t group; /**< 0 - 1st IO group, 1 - 2nd IO group */
|
||||||
|
uint8_t reserved[2];
|
||||||
|
} chn_info[4]; /**< Device connection information */
|
||||||
|
struct xpi_device_info_t device_info; /**< Device info, offset 0x20 */
|
||||||
|
struct xpi_instr_seq_t instr_set[xpi_std_nor_seq_idx_max];/**< Standard instruction sequence table, offset 0x70 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FLASH runtime context structure
|
||||||
|
*/
|
||||||
|
union flash_run_context_t {
|
||||||
|
struct {
|
||||||
|
uint32_t wait_time: 7; /**< Wait time */
|
||||||
|
uint32_t wait_time_unit: 1; /**< 0 - 10us, 1 - 1ms */
|
||||||
|
uint32_t reset_gpio: 8; /**<Reset GPIO */
|
||||||
|
uint32_t restore_sequence: 4; /**<Restore sequence */
|
||||||
|
uint32_t exit_no_cmd_sequence: 4; /**< Exit no-cmd sequence */
|
||||||
|
uint32_t current_mode: 4; /**< Current FLASH mode */
|
||||||
|
uint32_t por_mode: 4; /**< FLASH mode upon Power-on Reset */
|
||||||
|
};
|
||||||
|
uint32_t U;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR API error codes
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
status_xpi_nor_sfdp_not_found = MAKE_STATUS(status_group_xpi_nor, 0), /**< SFDP table was not found */
|
||||||
|
status_xpi_nor_ddr_read_dummy_cycle_probe_failed =
|
||||||
|
MAKE_STATUS(status_group_xpi_nor, 1), /**< Probing Dummy cyles for DDR read failed */
|
||||||
|
status_xpi_nor_flash_not_found = MAKE_STATUS(status_group_xpi_nor, 2), /**< FLASH was not detected */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XPI NOR driver interface
|
||||||
|
*/
|
||||||
|
struct xpi_nor_driver_interface_t {
|
||||||
|
/**< XPI NOR driver interface: API version */
|
||||||
|
uint32_t version;
|
||||||
|
/**< XPI NOR driver interface: Get FLASH configuration */
|
||||||
|
hpm_stat_t (*get_config)(uint32_t *base,
|
||||||
|
struct xpi_nor_config_t *nor_cfg,
|
||||||
|
struct xpi_nor_config_option_t *cfg_option);
|
||||||
|
/**< XPI NOR driver interface: initialize FLASH */
|
||||||
|
hpm_stat_t (*init)(uint32_t *base, struct xpi_nor_config_t *nor_config);
|
||||||
|
/**< XPI NOR driver interface: Enable write access to FLASH */
|
||||||
|
hpm_stat_t
|
||||||
|
(*enable_write)(uint32_t *base, enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config, uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: Get FLASH status register */
|
||||||
|
hpm_stat_t (*get_status)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
uint32_t addr,
|
||||||
|
uint16_t *out_status);
|
||||||
|
/**< XPI NOR driver interface: Wait when FLASH is still busy */
|
||||||
|
hpm_stat_t
|
||||||
|
(*wait_busy)(uint32_t *base, enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config, uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: erase a specified FLASH region */
|
||||||
|
hpm_stat_t (*erase)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
uint32_t start,
|
||||||
|
uint32_t length);
|
||||||
|
/**< XPI NOR driver interface: Erase the whole FLASH */
|
||||||
|
hpm_stat_t (*erase_chip)(uint32_t *base, enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config);
|
||||||
|
/**< XPI NOR driver interface: Erase specified FLASH sector */
|
||||||
|
hpm_stat_t
|
||||||
|
(*erase_sector)(uint32_t *base, enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config, uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: Erase specified FLASH block */
|
||||||
|
hpm_stat_t
|
||||||
|
(*erase_block)(uint32_t *base, enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config, uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: Program data to specified FLASH address */
|
||||||
|
hpm_stat_t (*program)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
const uint32_t *src,
|
||||||
|
uint32_t dst_addr,
|
||||||
|
uint32_t length);
|
||||||
|
/**< XPI NOR driver interface: read data from specified FLASH address */
|
||||||
|
hpm_stat_t (*read)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
uint32_t *dst,
|
||||||
|
uint32_t start,
|
||||||
|
uint32_t length);
|
||||||
|
/**< XPI NOR driver interface: program FLASH page using nonblocking interface */
|
||||||
|
hpm_stat_t (*page_program_nonblocking)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
const uint32_t *src,
|
||||||
|
uint32_t dst_addr,
|
||||||
|
uint32_t length);
|
||||||
|
/**< XPI NOR driver interface: erase FLASH sector using nonblocking interface */
|
||||||
|
hpm_stat_t (*erase_sector_nonblocking)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: erase FLASH block using nonblocking interface */
|
||||||
|
hpm_stat_t (*erase_block_nonblocking)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config,
|
||||||
|
uint32_t addr);
|
||||||
|
/**< XPI NOR driver interface: erase the whole FLASh using nonblocking interface */
|
||||||
|
hpm_stat_t (*erase_chip_nonblocking)(uint32_t *base,
|
||||||
|
enum xpi_xfer_channel_t channel,
|
||||||
|
const struct xpi_nor_config_t *nor_config);
|
||||||
|
|
||||||
|
uint32_t reserved0[3];
|
||||||
|
|
||||||
|
/**< XPI NOR driver interface: automatically configuration flash based on the cfg_option setting */
|
||||||
|
hpm_stat_t (*auto_config)(uint32_t *base, struct xpi_nor_config_t *nor_cfg,
|
||||||
|
struct xpi_nor_config_option_t *cfg_option);
|
||||||
|
|
||||||
|
/**< XPI NOR driver interface: Get FLASH properties */
|
||||||
|
hpm_stat_t (*get_property)(uint32_t *base, struct xpi_nor_config_t *nor_cfg, uint32_t property_id, uint32_t *value);
|
||||||
|
|
||||||
|
uint32_t reserved1;
|
||||||
|
|
||||||
|
/**< Post Erase Sector Nonblocking operation: For Hybrid mode only */
|
||||||
|
hpm_stat_t (*post_erase_sector_nonblocking)(uint32_t *base, enum xpi_xfer_channel_t chn,
|
||||||
|
struct xpi_nor_config_t *nor_cfg, uint32_t addr);
|
||||||
|
|
||||||
|
/**< Post Erase Block Nonblocking operation: For Hybrid mode only */
|
||||||
|
hpm_stat_t (*post_erase_block_nonblocking)(uint32_t *base, enum xpi_xfer_channel_t chn,
|
||||||
|
struct xpi_nor_config_t *nor_cfg, uint32_t addr);
|
||||||
|
|
||||||
|
/**< Post Erase Chip Nonblocking operation: For Hybrid mode only */
|
||||||
|
hpm_stat_t (*post_erase_chip_nonblocking)(uint32_t *base, enum xpi_xfer_channel_t chn,
|
||||||
|
struct xpi_nor_config_t *nor_cfg);
|
||||||
|
|
||||||
|
/**< Post Page Program Nonblocking operation: For Hybrid mode only */
|
||||||
|
hpm_stat_t (*post_page_program_nonblocking)(uint32_t *base, enum xpi_xfer_channel_t chn,
|
||||||
|
struct xpi_nor_config_t *nor_config,
|
||||||
|
const uint32_t *src, uint32_t dst_addr, uint32_t length);
|
||||||
|
/**< Turn on the power for Internal FLASH */
|
||||||
|
void (*sip_flash_power_on)(uint32_t *base);
|
||||||
|
|
||||||
|
/**< Turn off the power for Internal FLASH */
|
||||||
|
void (*sip_flash_power_off)(uint32_t *base);
|
||||||
|
|
||||||
|
/**< Enable Hybrid mode */
|
||||||
|
void (*enable_hybrid_xpi)(uint32_t *base);
|
||||||
|
|
||||||
|
/**< Disable Hybrid mode */
|
||||||
|
void (*disable_hybrid_xpi)(uint32_t *base);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* HPM_ROMAPI_XPI_NOR_DEF_H */
|
||||||
69
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h
Normal file
69
contrib/loaders/flash/hpmicro/hpm_romapi_xpi_soc_def.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 HPMicro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HPM_ROMAPI_XPI_SOC_DEF_H
|
||||||
|
#define HPM_ROMAPI_XPI_SOC_DEF_H
|
||||||
|
|
||||||
|
#include "hpm_common.h"
|
||||||
|
#include "hpm_romapi_xpi_def.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************
|
||||||
|
* Definitions
|
||||||
|
**********************************************************************************************************************/
|
||||||
|
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_30MHZ (1U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_50MHZ (2U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_66MHZ (3U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_80MHZ (4U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_104MHZ (5U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_120MHZ (6U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_133MHZ (7U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_166MHZ (8U)
|
||||||
|
#define XPI_CLK_OUT_FREQ_OPTION_200MHZ (9U)
|
||||||
|
|
||||||
|
struct xpi_io_config_t {
|
||||||
|
uint8_t data_pads;
|
||||||
|
enum xpi_channel_t channel;
|
||||||
|
enum xpi_io_group_t io_group;
|
||||||
|
uint8_t drive_strength;
|
||||||
|
bool enable_dqs;
|
||||||
|
bool enable_diff_clk;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum clk_freq_type_t {
|
||||||
|
xpi_freq_type_typical,
|
||||||
|
xpi_freq_type_mhz,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum xpi_clk_src_t {
|
||||||
|
xpi_clk_src_auto,
|
||||||
|
xpi_clk_src_osc,
|
||||||
|
xpi_clk_src_pll0clk0,
|
||||||
|
xpi_clk_src_pll1clk0,
|
||||||
|
xpi_clk_src_pll1clk1,
|
||||||
|
xpi_clk_src_pll2clk0,
|
||||||
|
xpi_clk_src_pll2clk1,
|
||||||
|
xpi_clk_src_pll3clk0,
|
||||||
|
xpi_clk_src_pll4clk0,
|
||||||
|
};
|
||||||
|
|
||||||
|
union xpi_clk_config_t {
|
||||||
|
struct {
|
||||||
|
uint8_t freq;
|
||||||
|
bool enable_ddr;
|
||||||
|
enum xpi_clk_src_t clk_src;
|
||||||
|
enum clk_freq_type_t freq_type;
|
||||||
|
};
|
||||||
|
uint32_t freq_opt;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum xpi_clock_t {
|
||||||
|
xpi_clock_bus,
|
||||||
|
xpi_clock_serial_root,
|
||||||
|
xpi_clock_serial,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* HPM_ROMAPI_XPI_SOC_DEF_H */
|
||||||
17
contrib/loaders/flash/hpmicro/hpm_xpi_flash.h
Normal file
17
contrib/loaders/flash/hpmicro/hpm_xpi_flash.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 hpmicro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HPM_XPI_FLASH_H
|
||||||
|
#define HPM_XPI_FLASH_H
|
||||||
|
|
||||||
|
#define FLASH_INIT (0)
|
||||||
|
#define FLASH_ERASE (0x6)
|
||||||
|
#define FLASH_PROGRAM (0xc)
|
||||||
|
#define FLASH_READ (0x12)
|
||||||
|
#define FLASH_GET_INFO (0x18)
|
||||||
|
#define FLASH_ERASE_CHIP (0x1e)
|
||||||
|
|
||||||
|
#endif
|
||||||
72
contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc
Normal file
72
contrib/loaders/flash/hpmicro/hpm_xpi_flash.inc
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* Autogenerated with ../../../../src/helper/bin2char.sh */
|
||||||
|
0xef,0x00,0x20,0x05,0x02,0x90,0xef,0x00,0x60,0x12,0x02,0x90,0xef,0x00,0xe0,0x1f,
|
||||||
|
0x02,0x90,0xef,0x00,0x00,0x23,0x02,0x90,0xef,0x00,0x40,0x26,0x02,0x90,0xef,0x00,
|
||||||
|
0xa0,0x27,0x02,0x90,0xef,0x00,0xe0,0x28,0x02,0x90,0x9c,0x41,0x05,0x47,0xbd,0x8b,
|
||||||
|
0x63,0x7b,0xf7,0x00,0x9c,0x45,0x05,0x67,0x13,0x07,0x07,0xf0,0xf9,0x8f,0x13,0x07,
|
||||||
|
0x00,0x10,0x63,0x83,0xe7,0x00,0x82,0x80,0x23,0x20,0x05,0x06,0x23,0x22,0x05,0x06,
|
||||||
|
0x82,0x80,0x39,0x71,0x22,0xdc,0x13,0x04,0x40,0x2b,0x83,0x47,0x44,0x00,0x06,0xde,
|
||||||
|
0x18,0xc0,0xcd,0xe3,0x26,0xda,0x4a,0xd8,0x4e,0xd6,0x52,0xd4,0x56,0xd2,0xba,0x84,
|
||||||
|
0x2e,0x8a,0xb2,0x89,0x36,0x89,0x89,0x47,0x73,0xb0,0xa7,0x7c,0x13,0x07,0x84,0x00,
|
||||||
|
0x13,0x06,0x00,0x10,0x81,0x45,0x3a,0x85,0xb7,0x0a,0x02,0x20,0x02,0xcc,0x02,0xce,
|
||||||
|
0x05,0x2e,0x83,0xa6,0x4a,0xf1,0x93,0x57,0x79,0x00,0x89,0x8b,0xf4,0x46,0xaa,0x85,
|
||||||
|
0x52,0xc6,0x4e,0xc8,0x4a,0xca,0x23,0x24,0xf4,0x10,0x70,0x00,0x26,0x85,0x93,0x8a,
|
||||||
|
0x0a,0xf0,0x82,0x96,0x29,0xed,0x03,0xa7,0x4a,0x01,0xb7,0x07,0x01,0x56,0x93,0x87,
|
||||||
|
0xf7,0x2f,0x14,0x43,0x63,0xf5,0xd7,0x00,0x3c,0x5b,0x08,0x40,0x82,0x97,0xb2,0x47,
|
||||||
|
0x05,0x47,0xbd,0x8b,0x63,0x7b,0xf7,0x00,0xd2,0x47,0x05,0x67,0x13,0x07,0x07,0xf0,
|
||||||
|
0xf9,0x8f,0x13,0x07,0x00,0x10,0x63,0x8d,0xe7,0x02,0x83,0x47,0x44,0x00,0x23,0x0e,
|
||||||
|
0x04,0x02,0x81,0xe7,0x85,0x47,0x23,0x02,0xf4,0x00,0xd2,0x54,0x42,0x59,0xb2,0x59,
|
||||||
|
0x22,0x5a,0x92,0x5a,0xf2,0x50,0x62,0x54,0x01,0x45,0x21,0x61,0x82,0x80,0xf2,0x50,
|
||||||
|
0x62,0x54,0xd2,0x54,0x42,0x59,0xb2,0x59,0x22,0x5a,0x92,0x5a,0x21,0x61,0x82,0x80,
|
||||||
|
0x1c,0x40,0x23,0xa0,0x07,0x06,0x23,0xa2,0x07,0x06,0xc1,0xb7,0xb7,0x07,0x02,0x20,
|
||||||
|
0x83,0xa6,0x47,0xf1,0x01,0x11,0xb7,0x07,0x01,0x56,0x98,0x42,0x22,0xcc,0x4a,0xc8,
|
||||||
|
0x06,0xce,0x26,0xca,0x4e,0xc6,0x56,0xc2,0x93,0x87,0xf7,0x2f,0x2e,0x89,0x32,0x84,
|
||||||
|
0x63,0xf4,0xe7,0x00,0x33,0x89,0xa5,0x00,0x93,0x09,0x40,0x2b,0x83,0xd4,0x09,0x03,
|
||||||
|
0xaa,0x04,0x63,0x69,0x94,0x06,0xb3,0x7a,0x99,0x02,0x52,0xc4,0x33,0x8a,0x54,0x41,
|
||||||
|
0x63,0x80,0x44,0x03,0x9c,0x4e,0x83,0xa5,0x89,0x10,0x03,0xa5,0x09,0x00,0x52,0x87,
|
||||||
|
0xca,0x86,0x13,0x86,0x89,0x00,0x82,0x97,0x05,0xed,0x05,0x8c,0x56,0x94,0x52,0x99,
|
||||||
|
0x63,0xf1,0x84,0x04,0x37,0x0a,0x02,0x20,0x93,0x0a,0xc0,0x2b,0x13,0x0a,0x0a,0xf0,
|
||||||
|
0x21,0xa0,0x26,0x99,0x63,0xf1,0x84,0x06,0x83,0x27,0x4a,0x01,0x83,0xa5,0x89,0x10,
|
||||||
|
0x03,0xa5,0x09,0x00,0xdc,0x53,0xca,0x86,0x56,0x86,0x82,0x97,0x05,0x8c,0x75,0xd1,
|
||||||
|
0x22,0x4a,0xf2,0x40,0x62,0x44,0xd2,0x44,0x42,0x49,0xb2,0x49,0x92,0x4a,0x05,0x61,
|
||||||
|
0x82,0x80,0x22,0x4a,0x01,0x45,0x75,0xd4,0x93,0x0a,0xc0,0x2b,0xb7,0x07,0x02,0x20,
|
||||||
|
0x93,0x87,0x07,0xf0,0xdc,0x4b,0x22,0x87,0x62,0x44,0x83,0xa5,0x89,0x10,0x03,0xa5,
|
||||||
|
0x09,0x00,0xf2,0x40,0xd2,0x44,0xb2,0x49,0x9c,0x4f,0xca,0x86,0x56,0x86,0x42,0x49,
|
||||||
|
0x92,0x4a,0x05,0x61,0x82,0x87,0x22,0x4a,0xd1,0xbf,0xb7,0x07,0x02,0x20,0x83,0xa8,
|
||||||
|
0x47,0xf1,0xb7,0x07,0x01,0x56,0x13,0x88,0xf7,0x2f,0x03,0xa3,0x08,0x00,0x2e,0x87,
|
||||||
|
0xb6,0x87,0x63,0x74,0x68,0x00,0x33,0x87,0xa5,0x00,0x13,0x08,0x40,0x2b,0x83,0xa8,
|
||||||
|
0x88,0x02,0x83,0x25,0x88,0x10,0x03,0x25,0x08,0x00,0xb2,0x86,0x13,0x06,0x88,0x00,
|
||||||
|
0x82,0x88,0xb7,0x07,0x02,0x20,0x03,0xa3,0x47,0xf1,0xb7,0x07,0x01,0x56,0x13,0x88,
|
||||||
|
0xf7,0x2f,0x03,0x2e,0x03,0x00,0xae,0x88,0x32,0x87,0xb6,0x87,0x63,0x74,0xc8,0x01,
|
||||||
|
0x33,0x07,0xa6,0x00,0x13,0x08,0x40,0x2b,0x03,0x23,0xc3,0x02,0x83,0x25,0x88,0x10,
|
||||||
|
0x03,0x25,0x08,0x00,0xc6,0x86,0x13,0x06,0x88,0x00,0x02,0x83,0x81,0xcd,0x93,0x07,
|
||||||
|
0x40,0x2b,0x98,0x57,0x83,0xd7,0xe7,0x02,0x01,0x45,0x2a,0x07,0xaa,0x07,0x98,0xc1,
|
||||||
|
0xdc,0xc1,0x82,0x80,0x09,0x45,0x82,0x80,0xb7,0x07,0x02,0x20,0x93,0x87,0x07,0xf0,
|
||||||
|
0xdc,0x4b,0x13,0x06,0x40,0x2b,0x83,0x25,0x86,0x10,0x08,0x42,0xdc,0x4f,0x21,0x06,
|
||||||
|
0x82,0x87,0x82,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x3d,0x43,0x2a,0x87,0x63,0x73,0xc3,0x02,0x93,0x77,0xf7,0x00,0xbd,0xef,0xad,0xe5,
|
||||||
|
0x93,0x76,0x06,0xff,0x3d,0x8a,0xba,0x96,0x0c,0xc3,0x4c,0xc3,0x0c,0xc7,0x4c,0xc7,
|
||||||
|
0x41,0x07,0xe3,0x6b,0xd7,0xfe,0x11,0xe2,0x82,0x80,0xb3,0x06,0xc3,0x40,0x8a,0x06,
|
||||||
|
0x97,0x02,0x00,0x00,0x96,0x96,0x67,0x80,0xa6,0x00,0x23,0x07,0xb7,0x00,0xa3,0x06,
|
||||||
|
0xb7,0x00,0x23,0x06,0xb7,0x00,0xa3,0x05,0xb7,0x00,0x23,0x05,0xb7,0x00,0xa3,0x04,
|
||||||
|
0xb7,0x00,0x23,0x04,0xb7,0x00,0xa3,0x03,0xb7,0x00,0x23,0x03,0xb7,0x00,0xa3,0x02,
|
||||||
|
0xb7,0x00,0x23,0x02,0xb7,0x00,0xa3,0x01,0xb7,0x00,0x23,0x01,0xb7,0x00,0xa3,0x00,
|
||||||
|
0xb7,0x00,0x23,0x00,0xb7,0x00,0x82,0x80,0x93,0xf5,0xf5,0x0f,0x93,0x96,0x85,0x00,
|
||||||
|
0xd5,0x8d,0x93,0x96,0x05,0x01,0xd5,0x8d,0x61,0xb7,0x93,0x96,0x27,0x00,0x97,0x02,
|
||||||
|
0x00,0x00,0x96,0x96,0x86,0x82,0xe7,0x80,0x86,0xfa,0x96,0x80,0xc1,0x17,0x1d,0x8f,
|
||||||
|
0x3e,0x96,0xe3,0x74,0xc3,0xf8,0xa5,0xb7,
|
||||||
48
contrib/loaders/flash/hpmicro/linker.ld
Normal file
48
contrib/loaders/flash/hpmicro/linker.ld
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 HPMicro
|
||||||
|
*/
|
||||||
|
ENTRY(_init)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : {
|
||||||
|
*(.func_table)
|
||||||
|
KEEP(*(.flash_algo.text*))
|
||||||
|
KEEP(*(.rodata))
|
||||||
|
KEEP(*(.rodata*))
|
||||||
|
KEEP(*(.flash_algo.data*))
|
||||||
|
*(.text)
|
||||||
|
*(.text*)
|
||||||
|
__etext = .;
|
||||||
|
}
|
||||||
|
.discard : {
|
||||||
|
__noncacheable_start__ = .;
|
||||||
|
__noncacheable_bss_start__ = .;
|
||||||
|
__bss_start__ = .;
|
||||||
|
__bss_end__ = .;
|
||||||
|
__noncacheable_bss_end__ = .;
|
||||||
|
_end = .;
|
||||||
|
__noncacheable_init_start__ = .;
|
||||||
|
__data_start__ = .;
|
||||||
|
__data_end__ = .;
|
||||||
|
__noncacheable_init_end__ = .;
|
||||||
|
__noncacheable_end__ = .;
|
||||||
|
__heap_start__ = .;
|
||||||
|
__heap_end__ = .;
|
||||||
|
__ramfunc_start__ = .;
|
||||||
|
__ramfunc_end__ = .;
|
||||||
|
__noncacheable_bss_start__ = .;
|
||||||
|
__noncacheable_bss_end__ = .;
|
||||||
|
__noncacheable_init_start__ = .;
|
||||||
|
__noncacheable_init_end__ = .;
|
||||||
|
__tdata_start__ = .;
|
||||||
|
__tdata_end__ = .;
|
||||||
|
__tbss_start__ = .;
|
||||||
|
__tbss_end__ = .;
|
||||||
|
__data_load_addr__ = .;
|
||||||
|
__fast_load_addr__ = .;
|
||||||
|
__tdata_load_addr__ = .;
|
||||||
|
__noncacheable_init_load_addr__ = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
154
contrib/loaders/flash/hpmicro/openocd_flash_algo.c
Normal file
154
contrib/loaders/flash/hpmicro/openocd_flash_algo.c
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 HPMicro
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hpm_romapi.h"
|
||||||
|
|
||||||
|
#define CSR_MCACHE_CTL (0x7CA)
|
||||||
|
#define HPM_MCACHE_CTL_DC_EN_MASK (0x2UL)
|
||||||
|
|
||||||
|
#define XPI_USE_PORT_B_MASK (0x100)
|
||||||
|
#define XPI_USE_PORT_A_MASK (0)
|
||||||
|
#define XPI_USE_PORT_SHIFT (0x8)
|
||||||
|
|
||||||
|
#define ROMAPI_SUPPORTS_HYBRIDXPI() (ROM_API_TABLE_ROOT->xpi_nor_driver_if->version >= 0x56010300)
|
||||||
|
|
||||||
|
struct hpm_flash_info_t {
|
||||||
|
uint32_t total_sz_in_bytes;
|
||||||
|
uint32_t sector_sz_in_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.data"))) struct xpi_nor_config_t nor_config;
|
||||||
|
__attribute__ ((section(".flash_algo.data"))) bool xpi_inited = false;
|
||||||
|
__attribute__ ((section(".flash_algo.data"))) uint32_t channel = xpi_channel_a1;
|
||||||
|
__attribute__ ((section(".flash_algo.data"))) uint32_t *xpi_base;
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) void refresh_device_size(uint32_t *base,
|
||||||
|
struct xpi_nor_config_option_t *option)
|
||||||
|
{
|
||||||
|
volatile uint32_t *dev_size = (volatile uint32_t *)((uint32_t)base + 0x60);
|
||||||
|
bool enable_channelb = false;
|
||||||
|
if (option->header.words > 1)
|
||||||
|
enable_channelb = option->option1.connection_sel == xpi_nor_connection_sel_chnb_cs0;
|
||||||
|
if (enable_channelb) {
|
||||||
|
dev_size[0] = 0;
|
||||||
|
dev_size[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_init(uint32_t flash_base, uint32_t header,
|
||||||
|
uint32_t opt0, uint32_t opt1, uint32_t xpi_base_addr)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
struct xpi_nor_config_option_t cfg_option;
|
||||||
|
hpm_stat_t stat = status_success;
|
||||||
|
|
||||||
|
xpi_base = (uint32_t *)xpi_base_addr;
|
||||||
|
if (xpi_inited)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
__asm volatile("csrc %0, %1" : : "i"(CSR_MCACHE_CTL), "r"(HPM_MCACHE_CTL_DC_EN_MASK));
|
||||||
|
for (i = 0; i < sizeof(cfg_option); i++)
|
||||||
|
*((uint8_t *)&cfg_option + i) = 0;
|
||||||
|
for (i = 0; i < sizeof(nor_config); i++)
|
||||||
|
*((uint8_t *)&nor_config + i) = 0;
|
||||||
|
|
||||||
|
cfg_option.header.U = header;
|
||||||
|
cfg_option.option0.U = opt0;
|
||||||
|
cfg_option.option1.U = opt1;
|
||||||
|
|
||||||
|
if (opt1 & XPI_USE_PORT_B_MASK)
|
||||||
|
channel = xpi_channel_b1;
|
||||||
|
else
|
||||||
|
channel = xpi_channel_a1;
|
||||||
|
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->auto_config(xpi_base, &nor_config, &cfg_option);
|
||||||
|
if (stat)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
if (ROMAPI_SUPPORTS_HYBRIDXPI())
|
||||||
|
ROM_API_TABLE_ROOT->xpi_nor_driver_if->enable_hybrid_xpi(xpi_base);
|
||||||
|
|
||||||
|
refresh_device_size(xpi_base, &cfg_option);
|
||||||
|
|
||||||
|
nor_config.device_info.clk_freq_for_non_read_cmd = 0;
|
||||||
|
if (!xpi_inited)
|
||||||
|
xpi_inited = true;
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_erase(uint32_t flash_base, uint32_t address, uint32_t size)
|
||||||
|
{
|
||||||
|
hpm_stat_t stat = status_success;
|
||||||
|
uint32_t left, start, block_size, align;
|
||||||
|
|
||||||
|
left = size;
|
||||||
|
start = address;
|
||||||
|
if (ROMAPI_SUPPORTS_HYBRIDXPI())
|
||||||
|
start += flash_base;
|
||||||
|
block_size = nor_config.device_info.block_size_kbytes * 1024;
|
||||||
|
if (left >= block_size) {
|
||||||
|
align = block_size - (start % block_size);
|
||||||
|
if (align != block_size) {
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, channel, &nor_config, start, align);
|
||||||
|
if (stat != status_success)
|
||||||
|
return stat;
|
||||||
|
left -= align;
|
||||||
|
start += align;
|
||||||
|
}
|
||||||
|
while (left > block_size) {
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_block(xpi_base, channel, &nor_config, start);
|
||||||
|
if (stat != status_success)
|
||||||
|
break;
|
||||||
|
left -= block_size;
|
||||||
|
start += block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stat == status_success && left)
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase(xpi_base, channel, &nor_config, start, left);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_program(uint32_t flash_base, uint32_t address,
|
||||||
|
uint32_t *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
hpm_stat_t stat;
|
||||||
|
|
||||||
|
if (ROMAPI_SUPPORTS_HYBRIDXPI())
|
||||||
|
address += flash_base;
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->program(xpi_base, channel, &nor_config, buf, address, size);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_read(uint32_t flash_base, uint32_t *buf,
|
||||||
|
uint32_t address, uint32_t size)
|
||||||
|
{
|
||||||
|
hpm_stat_t stat;
|
||||||
|
|
||||||
|
if (ROMAPI_SUPPORTS_HYBRIDXPI())
|
||||||
|
address += flash_base;
|
||||||
|
stat = ROM_API_TABLE_ROOT->xpi_nor_driver_if->read(xpi_base, channel, &nor_config, buf, address, size);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_get_info(uint32_t flash_base,
|
||||||
|
struct hpm_flash_info_t *flash_info)
|
||||||
|
{
|
||||||
|
if (!flash_info)
|
||||||
|
return status_invalid_argument;
|
||||||
|
|
||||||
|
flash_info->total_sz_in_bytes = nor_config.device_info.size_in_kbytes << 10;
|
||||||
|
flash_info->sector_sz_in_bytes = nor_config.device_info.sector_size_kbytes << 10;
|
||||||
|
return status_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) uint32_t flash_erase_chip(uint32_t flash_base)
|
||||||
|
{
|
||||||
|
return ROM_API_TABLE_ROOT->xpi_nor_driver_if->erase_chip(xpi_base, channel, &nor_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ ((section(".flash_algo.text"))) void flash_deinit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user