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;
							 | 
						||
| 
								 | 
							
								}
							 |