213 lines
5.4 KiB
C
213 lines
5.4 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "chip_reg_base.h"
|
|
#include "hw_reg_api.h"
|
|
#include "efuse.h"
|
|
#include "dbg_io.h"
|
|
#include "iot_errno_api.h"
|
|
#include "dtest_printf.h"
|
|
|
|
#define EFS_BRN_EFUSE_SIZE 128 /* 128 bytes totally. */
|
|
|
|
const static uint8_t g_efuse_data[] = {
|
|
/* ATE section. */
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
/* Bond section. */
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
/*
|
|
* IOmap section. Fpga looked up as 0x77543210,
|
|
* value = 0x77543210 | 0x80000000, MSB bit is valid-bit.
|
|
*/
|
|
0x10, 0x32, 0x54, 0xF7,
|
|
0x10, 0x32, 0x54, 0xF7,
|
|
|
|
/*
|
|
* System config section.
|
|
* 1. CRC check related to fastboot.
|
|
* 2. Enable message print.
|
|
*/
|
|
0x10, 0x10,
|
|
|
|
/* ANA1 section. */
|
|
0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00,
|
|
|
|
/*
|
|
* Patch config section.
|
|
* 1. Patch 0/4/5/6 enabled, 1/2/3/7 disabled;
|
|
* 2. #0 : pos-2, #4/5 : pos-3, #6 : pos-7;
|
|
* 3. #0 wirte memory *0x10000800 = 0x89ABCDEF;
|
|
* 4. #4/5 disable WDG0,*0x40040080 = 0x57444750, *0x40040008 = 0x0;
|
|
* 5. #6 put char 'Q' out of UART0, *0x40010000 = 0x51;
|
|
*/
|
|
0x71, 0x71,
|
|
0x02, 0x00, 0x33, 0x07,
|
|
|
|
/* Patch & ANA2 section. */
|
|
0x00, 0x08, 0x00, 0x10,
|
|
0xEF, 0xCD, 0xAB, 0x89,
|
|
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x80, 0x00, 0x04, 0x40,
|
|
0x50, 0x47, 0x44, 0x57,
|
|
|
|
0x08, 0x00, 0x04, 0x40,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x01, 0x40,
|
|
0x51, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
void efuse_phy_bit_prog(uint8_t efuse_byte_num, uint8_t bit_index);
|
|
uint8_t efuse_phy_byte_read(uint8_t efuse_byte_num);
|
|
void efuse_reg_byte_prog(uint8_t efuse_byte_num, uint8_t data);
|
|
uint8_t efuse_reg_byte_read(uint8_t efuse_byte_num);
|
|
|
|
/*
|
|
* This will write a byte of data into efuse HW & register.
|
|
* offset : 0 ~ 127.
|
|
*/
|
|
void efuse_byte_program(uint32_t offset, uint8_t val)
|
|
{
|
|
uint32_t bit_idx;
|
|
|
|
/* Program 0 ~ 7 bit. */
|
|
for (bit_idx = 0; bit_idx < 8; bit_idx++) {
|
|
if (val & (1 << bit_idx)) {
|
|
efuse_phy_bit_prog(offset, bit_idx);
|
|
}
|
|
}
|
|
|
|
/* Write 8 bits into reg. */
|
|
efuse_reg_byte_prog(offset, val);
|
|
|
|
return;
|
|
}
|
|
|
|
void efuse_data_write(const uint8_t *p_data)
|
|
{
|
|
uint32_t byte_idx;
|
|
uint8_t *p_val = (uint8_t *)p_data;
|
|
|
|
for (byte_idx = 0; byte_idx < EFS_BRN_EFUSE_SIZE; byte_idx ++) {
|
|
efuse_byte_program(byte_idx, *p_val++);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void efuse_data_register_read(uint8_t *p_data)
|
|
{
|
|
uint32_t byte_idx;
|
|
uint8_t *p_val = (uint8_t *)p_data;
|
|
|
|
for (byte_idx = 0; byte_idx < EFS_BRN_EFUSE_SIZE; byte_idx ++) {
|
|
*p_val++ = efuse_reg_byte_read(byte_idx);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void efuse_data_hardware_read(uint8_t *p_data)
|
|
{
|
|
uint32_t byte_idx;
|
|
uint8_t *p_val = (uint8_t *)p_data;
|
|
|
|
for (byte_idx = 0; byte_idx < EFS_BRN_EFUSE_SIZE; byte_idx ++) {
|
|
*p_val++ = efuse_phy_byte_read(byte_idx);
|
|
}
|
|
|
|
return;
|
|
}
|
|
uint32_t efuse_data_check_and_dump(const uint8_t *p_data)
|
|
{
|
|
uint8_t reg_buf[EFS_BRN_EFUSE_SIZE];
|
|
uint8_t hw_buf[EFS_BRN_EFUSE_SIZE];
|
|
uint32_t idx, ret = 0;
|
|
uint8_t * const org_buf = (uint8_t *)p_data;
|
|
|
|
efuse_data_hardware_read(hw_buf);
|
|
|
|
efuse_data_register_read(reg_buf);
|
|
|
|
for (idx = 0; idx < EFS_BRN_EFUSE_SIZE; idx ++) {
|
|
if ((org_buf[idx] != reg_buf[idx])
|
|
|| (org_buf[idx] != hw_buf[idx])) {
|
|
dprintf("Byte %d check failed, org %x, reg %x, hw %x!\r\n",
|
|
idx, org_buf[idx], reg_buf[idx], hw_buf[idx]);
|
|
ret = 1;
|
|
} else {
|
|
/* Check passed. */
|
|
dprintf("Byte %d value %x.\r\n", idx, org_buf[idx]);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Write all 128 bytes data into efuse.
|
|
*/
|
|
void efuse_data_burning(void)
|
|
{
|
|
uint32_t ret_error = 0;
|
|
|
|
if (EFS_BRN_EFUSE_SIZE != sizeof(g_efuse_data)) {
|
|
dprintf("Size of efuse mismatch !\r\n");
|
|
goto out;
|
|
}
|
|
|
|
dprintf("Start writting efuse data :\r\n");
|
|
|
|
efuse_data_write(g_efuse_data);
|
|
|
|
dprintf("Finish writting!\r\nStart check efuse data & dump :\r\n");
|
|
|
|
ret_error = efuse_data_check_and_dump(g_efuse_data);
|
|
|
|
if (ret_error) {
|
|
dprintf("Finish burning efuse, failed !\r\n");
|
|
} else {
|
|
dprintf("Finish burning efuse, successfully !\r\n");
|
|
}
|
|
|
|
out:
|
|
|
|
while(1) __asm volatile ("nop\n");
|
|
|
|
return;
|
|
} |