Files
2025-10-21 19:40:27 +08:00

131 lines
3.5 KiB
C

/**
* @file rom_ctrl.c
* @brief rom control source file
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#include <armv7-r/barriers.h>
#include <armv7-r/irq.h>
#include <core_id.h>
#include <part.h>
#include <reg.h>
#include <regs_base.h>
#include <rom_ctrl/rom_ctrl.h>
#include <reset_ip.h>
#include <scr_hw.h>
#include <sdrv_rstgen.h>
#include <sdrv_scr.h>
#define SFS_TAG 0x10000000
#define SFS_READ_XFER_CONFIG0 0x10000040
#define SFS_READ_XFER_CONFIG1 0x10000044
#define SFS_TAG_VAL 0x53465301
#define ROM_CTRL_FLASH_LINE_NUMBER_SHIFT 1
#define ROM_CTRL_FLASH_CMD_SHIFT 3
#define ROM_CTRL_FLASH_CTRL_VALID_SHIFT 5
#define ROM_CTRL_BOOT_PIN_OVERRIDE_BIT_OFFSET 0x1
#define ROM_CTRL_BOOT_PIN_OVERRIDE_ENABLE_BIT_OFFSET 0x9
/**
* @brief Read rom control data.
*
* @return rom control data
*/
static uint8_t get_rom_ctrl_data(void)
{
uint8_t line_num = 0;
uint8_t ret = 0;
#if CONFIG_RD_CFG_FROM_XSPI /* read config from xspi reg */
uint32_t xspi_rd_cfg = readl(APB_XSPI1PORTA_BASE + 0x100);
line_num = (xspi_rd_cfg >> 0) & 0x3;
ret = (xspi_rd_cfg >> 26) & 0x1; // ddr or sdr
#else /* read config from sfs file */
if (readl(SFS_TAG) != SFS_TAG_VAL) {
return 0;
}
else {
line_num = (readl(SFS_READ_XFER_CONFIG0) >> 8) & 0x3;
ret = (readl(SFS_READ_XFER_CONFIG1) >> 26) & 0x1; // ddr or sdr
}
#endif
ret |= line_num << ROM_CTRL_FLASH_LINE_NUMBER_SHIFT; // line_num
ret |= 0 << ROM_CTRL_FLASH_CMD_SHIFT; // cmd
ret |= 1 << ROM_CTRL_FLASH_CTRL_VALID_SHIFT; // valid
return ret;
}
/**
* @brief Clear rom control boot pin mode flag.
*
* This function is used to clear rom control boot pin mode flag, call
* this function and processor software reset, processor boot from
* where is determined by the boot pin in hardware.
*/
static void sdrv_rom_ctrl_clear_boot_pin_flag(void)
{
uint32_t val = 0;
val = sdrv_rstgen_read_general(&reset_general_reg_rom_ctrl);
val &= ~0x1E;
val &= ~(0x1 << ROM_CTRL_BOOT_PIN_OVERRIDE_ENABLE_BIT_OFFSET);
sdrv_rstgen_write_general(&reset_general_reg_rom_ctrl, val);
}
/**
* @brief Set rom control boot pin mode flag.
*
* This function is used to set rom control boot pin mode flag, call this
* function and processor software reset, processor will boot from the
* set mode.
*
* @param [in] boot_mode boot mode
*/
void sdrv_rom_ctrl_set_boot_pin_flag(sdrv_rom_ctrl_boot_mode_e boot_mode)
{
uint32_t val = 0;
uint8_t boot_pin = 0;
switch (boot_mode) {
case SDRV_ROM_CTRL_BOOT_MODE_FLASH:
boot_pin = 0;
break;
case SDRV_ROM_CTRL_BOOT_MODE_EMMC:
boot_pin = 2;
break;
#if !CONFIG_E3L
case SDRV_ROM_CTRL_BOOT_MODE_SD2:
boot_pin = 4;
break;
#endif
case SDRV_ROM_CTRL_BOOT_MODE_USB:
boot_pin = 8;
break;
case SDRV_ROM_CTRL_BOOT_MODE_BOOT_PIN:
default:
sdrv_rom_ctrl_clear_boot_pin_flag();
return;
}
val = sdrv_rstgen_read_general(&reset_general_reg_rom_ctrl);
val |= ((boot_pin << ROM_CTRL_BOOT_PIN_OVERRIDE_BIT_OFFSET) & 0x1E);
val |= (0x1 << ROM_CTRL_BOOT_PIN_OVERRIDE_ENABLE_BIT_OFFSET);
sdrv_rstgen_write_general(&reset_general_reg_rom_ctrl, val);
}
/**
* @brief Update rom control data.
*/
void sdrv_rom_ctrl_data_update(void)
{
/* update rom ctrl data */
sdrv_rstgen_write_general_bit(&reset_general_reg_rom_ctrl, 24, 8, get_rom_ctrl_data());
}