Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,399 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "psram.h"
|
||||
#include "pmic.h"
|
||||
#include "cpu.h"
|
||||
#include "secureboot.h"
|
||||
#include "aboot.h"
|
||||
#include "reg.h"
|
||||
#include "smux.h"
|
||||
#include "property.h"
|
||||
#include "efuse.h"
|
||||
#include "syscall-arom.h"
|
||||
#include "pmu.h"
|
||||
#if defined(CPU_MODEL_CRANE)
|
||||
#include "freq.h"
|
||||
#include "mpu.h"
|
||||
#endif
|
||||
|
||||
#define NOT_MCU_CR5 ((AROM_VERSION != AROM_VER_2022_08_08_CRANEW_CR5))
|
||||
|
||||
#define SUPPORT_DDR_MEMORY (AROM_VERSION == AROM_VER_2022_11_11_CRANEG_CR5)
|
||||
|
||||
#define SUPPORT_PSRAM_MEMORY (AROM_VERSION != AROM_VER_2022_11_11_CRANEG_CR5 && \
|
||||
AROM_VERSION != AROM_VER_2024_04_30_LAPWING_CR5 && \
|
||||
AROM_VERSION != AROM_VER_2022_08_08_CRANEW_CR5)
|
||||
#if SUPPORT_DDR_MEMORY
|
||||
#include "ddr.h"
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#define LOG_MODULE "Preboot"
|
||||
#define LOG_LEVEL LOG_LEVEL_MAIN
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define SUPPORT_BOOT_GO_TO_PRODUCTION 0
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if defined(CPU_MODEL_CRANE)
|
||||
extern char __lzma_decode_start, __lzma_decode_size;
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UMTI_BASE 0xD4207000
|
||||
#define USB_PHY_REG_04 0x10
|
||||
#define USB_PHY_REG_25 0x94
|
||||
#define USB_PHY_REG_28 0xA0
|
||||
#define USB_PHY_REG_29 0xA4
|
||||
#define HS_ISEL_MASK (0x3 << 12)
|
||||
#define HS_ISEL (0x3 << 12)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define QUECTEL_PREBOOT_OPT
|
||||
#ifdef QUECTEL_PREBOOT_OPT
|
||||
#include "i2c.h"
|
||||
static int Quec_PMIC_GET_PWEKY_STATUS(void)
|
||||
{
|
||||
uint8_t reg_val;
|
||||
pi2c_read_reg(0x01, ®_val);
|
||||
if(reg_val & (0x01<<1))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int Quec_PowerOnCheck(void)
|
||||
{
|
||||
unsigned int i=0;
|
||||
|
||||
//uart_printf("[Quec][PWK]OnkeyPowerOnCheck\r\n");
|
||||
/* Set 15s for power-down-by-long-ONKEY-pressing period, this register is
|
||||
restricted to change only one bit each time. */
|
||||
pi2c_init(PMIC_BASE_PAGE_ADDR);
|
||||
#if (AROM_VERSION == AROM_VER_2022_11_06_CRANEL_CR5)
|
||||
for(i=0;i<80;i++) // 1602ƽ̨ 520ms+100ms(run here need 270ms )= 620ms for powerkey check.
|
||||
#elif (AROM_VERSION == AROM_VER_2020_07_30_CRANEGM_A0)
|
||||
for(i=0;i<20;i++)
|
||||
#else
|
||||
for(i=0;i<5;i++) // 1606ƽ̨ 520ms+100ms(run here need 270ms )= 620ms for powerkey check.
|
||||
#endif
|
||||
{
|
||||
if (!Quec_PMIC_GET_PWEKY_STATUS())
|
||||
{
|
||||
LOG_PRINT("short press, do poweroff!!\r\n");
|
||||
clock_wait_ms(10); /* 100 ms */
|
||||
return 1; //Power down if ONKEY is not pressed long enough.
|
||||
}
|
||||
clock_wait_ms(1); /* 5 ms */
|
||||
}
|
||||
LOG_PRINT("long press, do poweron!!\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void quec_powerkey_check(void)
|
||||
{
|
||||
unsigned char power_up_flag = 0xff, i = 0;
|
||||
unsigned char val;
|
||||
int pmic_reset_retry = 3;
|
||||
unsigned char reg[10] = {0};
|
||||
|
||||
while(pmic_reset_retry--) {
|
||||
pi2c_bus_reset();
|
||||
pi2c_reset();
|
||||
pi2c_init(PMIC_BASE_PAGE_ADDR);
|
||||
if(pi2c_read_reg(PMIC_ID, &val) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pi2c_read_reg(0x01, ®[0]);//status
|
||||
pi2c_read_reg(0x10, ®[1]);
|
||||
pi2c_read_reg(0xe5, ®[2]);
|
||||
pi2c_read_reg(0xe6, ®[3]);
|
||||
pi2c_read_reg(0xe2, ®[4]);
|
||||
pi2c_read_reg(0xeb, ®[5]);
|
||||
LOG_PRINT("PMIC REG:0x01,0x10,0xe5,0xe6,0xe2,0xeb\r\n");
|
||||
LOG_PRINT("PMIC VAL:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\r\n",reg[0],reg[1],reg[2],reg[3],reg[4],reg[5]);
|
||||
if(smux_running_mode_get() == SMUX_MODE_NORMAL)
|
||||
{
|
||||
power_up_flag = 0x01; // hot power on
|
||||
LOG_PRINT("download mode, do power on\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PMIC_PID(val) == PM802)
|
||||
{
|
||||
pi2c_read_reg(0x10, ®[0]); //read power up log
|
||||
pi2c_read_reg(0xf0, ®[1]); //read xo reg
|
||||
pi2c_read_reg(0x01, ®[2]); //read exton1n status
|
||||
|
||||
if((reg[1] & 0xf0) == 0x0) //cold power up
|
||||
{
|
||||
if((reg[0] == 0x0) && ((reg[2] & 0x02) == 0)) // unkown wakeup source && pwrkey is not pressed
|
||||
{
|
||||
LOG_PRINT("unkown wakeup:%d, do power off!!!\n",reg[0]);
|
||||
|
||||
pi2c_write_reg(0xe2, 0xf0); //set discharger timer to 0S //default 2S
|
||||
pi2c_read_reg(0xe7, ®[0]);
|
||||
pi2c_write_reg(0xe7, (reg[0] & 0xfb)); //disalbe fault wakeup
|
||||
pi2c_read_reg(0x0d, ®[0]);
|
||||
pi2c_write_reg(0x0d, (reg[0])|0x20) ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
pi2c_write_reg(0xe2, 0xf1); //set discharger timer back to 1S
|
||||
}
|
||||
|
||||
if( 0 == (reg[5]&0x80))
|
||||
{
|
||||
power_up_flag = 0x00; // cold power on
|
||||
LOG_PRINT("cold power on\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
power_up_flag = 0x01; // hot power on
|
||||
LOG_PRINT("hot power on\n");
|
||||
}
|
||||
if(0x00 == power_up_flag) // cold power on
|
||||
{
|
||||
|
||||
if(Quec_PowerOnCheck())
|
||||
{
|
||||
LOG_PRINT("warning: powkey too short !!!!!\r\n");
|
||||
//quec_pmic_sw_pdown();
|
||||
pmic_sw_pdown();
|
||||
return;
|
||||
}
|
||||
//save hot flag
|
||||
pi2c_write_reg(0xeb, (reg[5] | 0x80));
|
||||
}
|
||||
}
|
||||
for(i = 0;i < 10; i++)
|
||||
{
|
||||
if(reg[i] == 0x0)
|
||||
{
|
||||
reg[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
reg[9] = 0x0;
|
||||
asr_property_set("power_down_reg", (const char*)(reg));
|
||||
}
|
||||
#endif
|
||||
void
|
||||
usb_phy_config(void)
|
||||
{
|
||||
unsigned val;
|
||||
unsigned chip_id;
|
||||
|
||||
chip_id = hw_chip_id();
|
||||
if(chip_id == CHIP_ID_CRANE) {
|
||||
/* driver strength */
|
||||
val = (unsigned)readl(UMTI_BASE + USB_PHY_REG_28);
|
||||
writel((val & ~HS_ISEL_MASK) | HS_ISEL, UMTI_BASE + USB_PHY_REG_28);
|
||||
LOG_PRINT("Usb phy reg 28 0x%x -> 0x%lx\n", val, readl(UMTI_BASE + USB_PHY_REG_28));
|
||||
} else if((CHIP_ID_CRANEG == chip_id) || (CHIP_ID_CRANEM == chip_id)) {
|
||||
val = (unsigned)readl(UMTI_BASE + USB_PHY_REG_29);
|
||||
writel((val & ~0x1F) | 0x1B, UMTI_BASE + USB_PHY_REG_29);
|
||||
LOG_PRINT("Usb phy reg 29 0x%x -> 0x%lx\n", val, readl(UMTI_BASE + USB_PHY_REG_29));
|
||||
val = (unsigned)readl(UMTI_BASE + USB_PHY_REG_25);
|
||||
writel(val | (BIT7), UMTI_BASE + USB_PHY_REG_25);
|
||||
val = (unsigned)readl(UMTI_BASE + USB_PHY_REG_04);
|
||||
writel(val | (BIT4 | BIT5 | BIT6), UMTI_BASE + USB_PHY_REG_04);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if defined(CPU_MODEL_CRANE) && (AROM_VERSION != AROM_VER_2024_04_30_LAPWING_CR5)
|
||||
static void
|
||||
psram_mpu_config(void)
|
||||
{
|
||||
#if SUPPORT_DDR_MEMORY
|
||||
extern char __ddr_base;
|
||||
unsigned base = (unsigned)&__ddr_base;
|
||||
unsigned size = get_ddr_size();
|
||||
#else
|
||||
extern char __psram_base;
|
||||
unsigned base = (unsigned)&__psram_base;
|
||||
unsigned size = get_psram_size();
|
||||
#endif
|
||||
|
||||
mpu_region_config(ATCM_CODE_REGION_NUM, 0x0, 0x10000, MPU_ATTR_RWX);
|
||||
mpu_region_config(PSRAM_DDR_REGION_NUM_RWX, base, size, MPU_ATTR_RWX);
|
||||
mpu_region_config(PSRAM_DDR_REGION_NUM_NONE, 0x0, 0x80000000, MPU_ATTR_NONE);
|
||||
|
||||
/* These used memory(>= 0x8000_0000) should be configurated to MPU normal,
|
||||
* if not configurated in bootrom for Cortex R5.
|
||||
*/
|
||||
#if (AROM_VERSION == AROM_VER_2020_07_30_CRANEGM_A0 || \
|
||||
AROM_VERSION == AROM_VER_2022_11_06_CRANEL_CR5)
|
||||
extern char __aram_ctext_start, __aram_ctext_size;
|
||||
mpu_region_config(L2SRAM_REGION_NUM, &__aram_ctext_start, &__aram_ctext_size, MPU_ATTR_RWX);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NOT_MCU_CR5
|
||||
static int
|
||||
pmic_config(void)
|
||||
{
|
||||
if(hw_platform_type() != HW_PLATFORM_TYPE_SILICON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pmic_setup();
|
||||
|
||||
uint8_t powerup_reason = pmic_powerup_get_reason();
|
||||
LOG_PRINT("Power_up_reason=0x%x.\n", powerup_reason);
|
||||
|
||||
pmic_fault_wu_en_disable();
|
||||
|
||||
uint8_t pmic_id = pmic_get_id();
|
||||
/* PM803 is different with others */
|
||||
uint8_t invalid_bits = (pmic_id == PM803) ? PM803_INVALID_STATE :
|
||||
PM813_INVALID_STATE;
|
||||
|
||||
if(powerup_reason & invalid_bits) {
|
||||
LOG_WARN("Warning: power_up_reason=0x%x is abnormal.\n", powerup_reason);
|
||||
/* pmic_sw_pdown(); */
|
||||
/* return 0; */
|
||||
}
|
||||
|
||||
switch(pmic_id) {
|
||||
case PM802:
|
||||
case PM802S:
|
||||
/* workaround for PM802, if power up log = 0 or 8(bat_wu_log), pmic power down. PM813 no this hardware bug. */
|
||||
if(0 == powerup_reason || 8 == powerup_reason) {
|
||||
LOG_WARN("Warning: power_up_reason = 0 or 8(bat_wu_log). need pmic power down\n");
|
||||
pmic_sw_pdown();
|
||||
/* never reach here. */
|
||||
}
|
||||
break;
|
||||
case PM813L:
|
||||
/* pmic813L A0's bug: onkey reason cannot set bit in powerup_reason, So add workaround */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
/*read or write geu, must enable clk at first, else, geu bank dump always be 0. */
|
||||
#if (AROM_VERSION != AROM_VER_2022_08_08_CRANEW_CR5)
|
||||
/* watch1 cr5 does not require the use of the GEU module. */
|
||||
geu_clk_enable();
|
||||
#endif
|
||||
|
||||
#if defined(CPU_MODEL_CRANE)
|
||||
cr5_axi_set_max_freq();
|
||||
#endif
|
||||
|
||||
LOG_PRINT("Executing preboot application...\n");
|
||||
LOG_PRINT("Preboot version: %s\n", BOOTLOADER_VERSION);
|
||||
|
||||
/* force init prop 1K space: 0XB0020C00~ 0xB0021000 */
|
||||
asr_property_area_init(1);
|
||||
asr_property_set("bl2.preboot.ver", BOOTLOADER_VERSION);
|
||||
|
||||
#if defined(CPU_MODEL_CRANE) || defined(CPU_MODEL_CRANEW_MCU)
|
||||
#if NOT_MCU_CR5
|
||||
/* arom-crane alread print log, this is only for set prop */
|
||||
if(!fuse_trust_boot_enabled()) {
|
||||
/*LOG_PRINT("### Non-trusted boot mode. ###\n"); */
|
||||
asr_property_set("bl1.secureboot", "0");
|
||||
} else {
|
||||
/*LOG_PRINT("### Trusted boot mode. ###\n"); */
|
||||
asr_property_set("bl1.secureboot", "1");
|
||||
}
|
||||
#else
|
||||
/*LOG_PRINT("### Non-trusted boot mode. ###\n"); */
|
||||
asr_property_set("bl1.secureboot", "0");
|
||||
#endif
|
||||
|
||||
#if NOT_MCU_CR5
|
||||
/*
|
||||
* "halt": When download completed, if usb pull out, board powerdown. defaultly it is "halt",
|
||||
* "reboot": some customer want to reboot instead of powerdown, so customer set it to "reboot" manually.
|
||||
* "noaction": if vbus is unconnected, usb_connect() is 0.
|
||||
* need set "noaction" to workaround the bug:
|
||||
* After download, flasher judges that it is usb pulled out, enter forcedown by mistake.
|
||||
*/
|
||||
asr_property_set("bl2.usb_disconnect", "halt");
|
||||
|
||||
/* enter production mode after go(boot continue) if bl2.go_production is true */
|
||||
#if SUPPORT_BOOT_GO_TO_PRODUCTION
|
||||
asr_property_set(PROP_NAME_GO_PRODUCTION, "true");
|
||||
#endif
|
||||
|
||||
usb_phy_config();
|
||||
|
||||
fuse_read_lotid();
|
||||
|
||||
//Move it to pmic_setuppmic_setup(void),after i2c initialization
|
||||
//#ifdef QUECTEL_PREBOOT_OPT
|
||||
// quec_powerkey_check();
|
||||
//#endif
|
||||
pmic_config();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AROM_VERSION == AROM_VER_2022_07_28_WATCH1
|
||||
if(efuse_modem_type_is_radio()) {
|
||||
asr_property_set("cp.modem.type", "MODEM_RADIO");
|
||||
} else {
|
||||
asr_property_set("cp.modem.type", "MODEM_ZERO");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SUPPORT_DDR_MEMORY)
|
||||
unsigned chip_id = hw_chip_id();
|
||||
if(chip_id == CHIP_ID_CRANEGT) {
|
||||
ddr_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SUPPORT_PSRAM_MEMORY)
|
||||
psram_init();
|
||||
#endif
|
||||
|
||||
#if AROM_VERSION == AROM_VER_2022_08_08_CRANEW_CR5
|
||||
/*
|
||||
* Watch1 cr5 psram is initialized in Harmony, and initialization is no longer repeated in
|
||||
* bootloader, mcu will write cr5 psram type to SW_SCRATCH(0xD4282CE8) register bit[15:8]
|
||||
* in Harmony, so cr5 read SW_SCRATCH bit[15:8] to get psram type here.
|
||||
*/
|
||||
char psram_type_str[PROP_VALUE_MAX] = "";
|
||||
extern void psram_type_name_get_by_sw_scratch(char *psram_type_str, size_t size);
|
||||
psram_type_name_get_by_sw_scratch(psram_type_str, sizeof(psram_type_str));
|
||||
asr_property_set("fuse.psram.type", psram_type_str);
|
||||
#endif
|
||||
|
||||
#if defined(CPU_MODEL_CRANE)
|
||||
#if (AROM_VERSION != AROM_VER_2024_04_30_LAPWING_CR5)
|
||||
psram_mpu_config();
|
||||
#endif
|
||||
/*
|
||||
* Atcm 64K is not enough to parse bootloder volume, so update to psram.
|
||||
*/
|
||||
LOG_INFO("Set fip image load address spaces to 0x%x\n",
|
||||
(unsigned)&__lzma_decode_start);
|
||||
sb_fip_image_setup((void *)&__lzma_decode_start, (unsigned)&__lzma_decode_size);
|
||||
#endif
|
||||
|
||||
#if (AROM_VERSION == AROM_VER_2022_08_08_CRANEW_CR5)
|
||||
uint32_t val = readl(CIU_BASE + SW_SCRATCH);
|
||||
val = (val & ~FLAGS_RUNNING_STAGE_MASK) | FLAGS_RUNNING_STAGE_PREBOOT_COMPLETE;
|
||||
writel(val, CIU_BASE + SW_SCRATCH);
|
||||
LOG_INFO("Set running stage: [0x%x] = 0x%x.\n", (CIU_BASE + SW_SCRATCH), (unsigned)readl(CIU_BASE + SW_SCRATCH));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
Reference in New Issue
Block a user