744 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			744 lines
		
	
	
		
			23 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. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | /* os shim includes */ | ||
|  | #include "os_types.h"
 | ||
|  | #include "os_utils.h"
 | ||
|  | #include "os_mem.h"
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #include "iot_diag.h"
 | ||
|  | #include "iot_io.h"
 | ||
|  | #include "ddr_reg_rf.h"
 | ||
|  | #include "dmc_reg_rf.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "ahb.h"
 | ||
|  | #include "k3d_reg.h"
 | ||
|  | #include "ai_glb_reg.h"
 | ||
|  | #include "mac_sys_reg.h"
 | ||
|  | #include "cpu.h"
 | ||
|  | 
 | ||
|  | // ############################################################################
 | ||
|  | // common define
 | ||
|  | #define REG32(a)    (*((volatile uint32_t *)(a)))
 | ||
|  | 
 | ||
|  | // common define end
 | ||
|  | // ############################################################################
 | ||
|  | 
 | ||
|  | // ############################################################################
 | ||
|  | // ddr define
 | ||
|  | //
 | ||
|  | #define DDR_CACHE_PRIME_ADDR    0x18000000
 | ||
|  | #define DDR_CACHE_TEST_LENGTH   (1024 * 1024 * 16)
 | ||
|  | #define MODE_REGISTER_WRITE 0xc0
 | ||
|  | #define MODE_REGISTER_READ 0x40
 | ||
|  | #define DDR_BASE    0x55228000
 | ||
|  | #define DDR_POERATION_INT_MEM3_ADDR (DDR_BASE + 0x11c)
 | ||
|  | #define DDR_RST_CFG_ADDR (DDR_BASE + 0x4)
 | ||
|  | 
 | ||
|  | #define MAC_PSRAM_DTEST 0
 | ||
|  | #define MCYCLE_ENA  1
 | ||
|  | 
 | ||
|  | typedef enum ddr_dev_x8_x16_mode { | ||
|  |     DEV_X8_MODE = 0, | ||
|  |     DEV_X16_MODE = 1, | ||
|  | }ddr_dev_x8_x16_mode_t; | ||
|  | // ddr define end
 | ||
|  | // ############################################################################
 | ||
|  | // ############################################################################
 | ||
|  | // ai define
 | ||
|  | #define AI_INNER_RAM0_ADDR  0x73000000
 | ||
|  | #define AI_INNER_RAM1_ADDR  0x73020000
 | ||
|  | 
 | ||
|  | #define AI_INNER_RAM_START_ADDR 0x10000
 | ||
|  | #define AI_INNER_RAM_END_ADDR   0x1680
 | ||
|  | 
 | ||
|  | #define AI_DDR_START_ADDR   0x800000
 | ||
|  | 
 | ||
|  | #define K3D_SUB_P 1
 | ||
|  | // ############################################################################
 | ||
|  | 
 | ||
|  | void ddr_op_clear() | ||
|  | { | ||
|  |     uint32_t tmp; | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 0); | ||
|  |     REG_FIELD_SET(PHY_EB_SOFT, tmp, 0); | ||
|  |     REG_FIELD_SET(SW_MEM_RD, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(DEV_OPERATION_SW, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |      tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 1); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 0); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  | } | ||
|  | void ddr_reg_write(uint8_t instruction, uint32_t addr, | ||
|  |         uint8_t write_lt, uint32_t wdata0, uint32_t wdata1) | ||
|  | { | ||
|  |     uint32_t tmp; | ||
|  | 
 | ||
|  |     // step 1
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_RD_OR_WR, tmp, 1); | ||
|  |     REG_FIELD_SET(SW_MEM_RD, tmp, 0); | ||
|  |     REG_FIELD_SET(PHY_EB_SOFT, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 1); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 0); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_CMD_DLY_CFG_ADDR); | ||
|  |     REG_FIELD_SET(DEV_WR_LATENCY, tmp, write_lt); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_CMD_DLY_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     // step 2
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(DEV_OPERATION_SW, tmp, 0); | ||
|  |     REG_FIELD_SET(DEV_CMD_SW, tmp, instruction); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG1_ADDR); | ||
|  |     REG_FIELD_SET(DEV_ADDR_SW, tmp, addr); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(DEV_OPERATION_SW, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     // step 3
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WDATA0, tmp, wdata0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR); | ||
|  |     REG_FIELD_SET(CMD_OR_DATA_FIFO, tmp, 0); | ||
|  |     if (instruction == MODE_REGISTER_WRITE) { | ||
|  |         REG_FIELD_SET(SW_MEM_WDATA1, tmp, 0x6db69a); | ||
|  |     } else { | ||
|  |         REG_FIELD_SET(SW_MEM_WDATA1, tmp, 0x69a69a); | ||
|  |     } | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR, tmp); | ||
|  | 
 | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WR, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WDATA0, tmp, wdata1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR); | ||
|  |     REG_FIELD_SET(CMD_OR_DATA_FIFO, tmp, 0); | ||
|  |     if (instruction == MODE_REGISTER_WRITE) { | ||
|  |         REG_FIELD_SET(SW_MEM_WDATA1, tmp, 0x6db6db); | ||
|  |     } else { | ||
|  |         REG_FIELD_SET(SW_MEM_WDATA1, tmp, 0x69a69a); | ||
|  |     } | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WR, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     // step 4
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WDATA0, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR); | ||
|  |     REG_FIELD_SET(CMD_OR_DATA_FIFO, tmp, 0); | ||
|  |     REG_FIELD_SET(SW_MEM_WDATA1, tmp, 0xaebaeb); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WR, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_WR, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(PHY_EB_SOFT, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     volatile uint32_t cnt = 50000; | ||
|  |     while(cnt--); | ||
|  | 
 | ||
|  |     ddr_op_clear(); | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | void ddr_reg_read(uint8_t instruction, uint32_t addr, | ||
|  |         uint32_t *rdata0, uint32_t *rdata1) | ||
|  | { | ||
|  |     uint32_t tmp; | ||
|  | 
 | ||
|  |     // step 1
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_RD_OR_WR, tmp, 0); | ||
|  |     REG_FIELD_SET(SW_MEM_RD, tmp, 0); | ||
|  |     REG_FIELD_SET(PHY_EB_SOFT, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 1); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_RST_CFG_ADDR); | ||
|  |     REG_FIELD_SET(RXTX_RAM_SOFT_RST, tmp, 0); | ||
|  |     REG_FIELD_SET(SAMPLE_REG_SOFT_RST, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_RST_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     // step 2
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(DEV_OPERATION_SW, tmp, 0); | ||
|  |     REG_FIELD_SET(DEV_CMD_SW, tmp, instruction); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG1_ADDR); | ||
|  |     REG_FIELD_SET(DEV_ADDR_SW, tmp, addr); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 0); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(DEV_OPERATION_SW, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_SOFT_CMD_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     for(volatile uint32_t i = 0; i < 100; i++); | ||
|  | 
 | ||
|  |     // step 3
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR); | ||
|  |     REG_FIELD_SET(SW_MEM_HANDLE_EB, tmp, 1); | ||
|  |     REG_FIELD_SET(PHY_EB_SOFT, tmp, 1); | ||
|  |     REG_FIELD_SET(SW_MEM_RD, tmp, 1); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_OPERATION_INT_MEM3_ADDR, tmp); | ||
|  | 
 | ||
|  |     // step 4
 | ||
|  |     /*
 | ||
|  |     uint32_t cnt = 0; | ||
|  |     while(1) { | ||
|  |         cnt++; | ||
|  |         *rdata0 = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM2_ADDR); | ||
|  |         *rdata1 = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM4_ADDR); | ||
|  |         if (*rdata0 != 0 && *rdata1 != 0) { | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     iot_printf("read cnt: %d\n", cnt); | ||
|  |     */ | ||
|  |     volatile uint32_t cnt = 1000; | ||
|  |     while(cnt--); | ||
|  |     *rdata0 = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM2_ADDR); | ||
|  |     *rdata1 = DDR_RF_READ_REG(CFG_DDR_OPERATION_INT_MEM4_ADDR); | ||
|  | 
 | ||
|  |     ddr_op_clear(); | ||
|  | } | ||
|  | 
 | ||
|  | void ddr_mode_sel(uint8_t bit_mode) | ||
|  | { | ||
|  | 
 | ||
|  |     uint32_t tmp; | ||
|  |     if (bit_mode == DEV_X8_MODE) { | ||
|  |         iot_printf("bit mode is X8\n"); | ||
|  |         tmp = DDR_RF_READ_REG(CFG_DDR_PROPERTY_CFG_ADDR); | ||
|  |         REG_FIELD_SET(DEV_CS_INTG, tmp, 1); | ||
|  |         REG_FIELD_SET(DEV_X8_X16_MODE, tmp, 0); | ||
|  |         DDR_RF_WRITE_REG(CFG_DDR_PROPERTY_CFG_ADDR, tmp); | ||
|  |     } else { | ||
|  |         iot_printf("bit mode is X16\n"); | ||
|  |         tmp = DDR_RF_READ_REG(CFG_DDR_PROPERTY_CFG_ADDR); | ||
|  |         REG_FIELD_SET(DEV_CS_INTG, tmp, 0); | ||
|  |         REG_FIELD_SET(DEV_X8_X16_MODE, tmp, 1); | ||
|  |         DDR_RF_WRITE_REG(CFG_DDR_PROPERTY_CFG_ADDR, tmp); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void ddr_module_cache_cfg() | ||
|  | { | ||
|  |     // disable cache
 | ||
|  |     iot_printf("disable cache\n"); | ||
|  |     ahb_cache_disable(); | ||
|  | 
 | ||
|  |     // ddr x16 mode
 | ||
|  |     iot_printf("set ddr x16 mode\n"); | ||
|  |     ddr_mode_sel(DEV_X16_MODE); | ||
|  |     uint8_t instruction; | ||
|  |     uint32_t rdata0, rdata1; | ||
|  | 
 | ||
|  |     for(uint32_t i = 0; i<=4; i++) { | ||
|  |         instruction = MODE_REGISTER_READ; | ||
|  |         ddr_reg_read(instruction, i, &rdata0, &rdata1); | ||
|  |         iot_printf("==instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, i, rdata0, rdata1); | ||
|  |     } | ||
|  |     // ddr write reg
 | ||
|  |     iot_printf("ddr write reg\n"); | ||
|  |     ddr_reg_write(MODE_REGISTER_WRITE, 0, 1, 0x01010101, 0x01010101); | ||
|  |     ddr_reg_write(MODE_REGISTER_WRITE, 4, 1, 0x0, 0x0); | ||
|  | 
 | ||
|  |     // set ddr read/write latency
 | ||
|  |     iot_printf("set ddr read/write latency\n"); | ||
|  |     uint32_t tmp; | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_CMD_DLY_CFG_ADDR); | ||
|  |     REG_FIELD_SET(DEV_RD_LATENCY, tmp, 3); | ||
|  |     REG_FIELD_SET(DEV_WR_LATENCY, tmp, 3); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_CMD_DLY_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     // set ddr chip size
 | ||
|  |     tmp = DDR_RF_READ_REG(CFG_DDR_PROPERTY_CFG_ADDR); | ||
|  |     REG_FIELD_SET(CS_SIZE, tmp, 0x7); | ||
|  |     DDR_RF_WRITE_REG(CFG_DDR_PROPERTY_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = DMC_RF_READ_REG(CFG_DMC_INF_CFG_ADDR); | ||
|  |     REG_FIELD_SET(DMC_TOTAL_SIZE, tmp, 0x7); | ||
|  |     DMC_RF_WRITE_REG(CFG_DMC_INF_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     // enable ahb cache
 | ||
|  |     iot_printf("cache enable\n"); | ||
|  |     ahb_cache_enable(); | ||
|  |     ahb_cache_reset(); | ||
|  | 
 | ||
|  |     // set cache ddr mode
 | ||
|  |     tmp = REG32(0x5000000c); | ||
|  |     tmp |= 0x180000; | ||
|  |     REG32(0x5000000c) = tmp; | ||
|  | 
 | ||
|  |     tmp = REG32(0x5000008c); | ||
|  |     tmp = 0x1004; | ||
|  |     REG32(0x5000008c) = tmp; | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t g_write_en = 0; | ||
|  | 
 | ||
|  | uint8_t g_cache_data[256] = {0}; | ||
|  | uint32_t g_cache32[16] = {0}; | ||
|  | extern uint8_t g_print_enable; | ||
|  | 
 | ||
|  | #if MAC_PSRAM_DTEST == 1
 | ||
|  | uint32_t start, end; | ||
|  | int64_t cost; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if MCYCLE_ENA == 1
 | ||
|  | uint64_t mcycle_start, mcycle_end; | ||
|  | uint64_t mcycle_cost; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | void ddr_module_test() | ||
|  | { | ||
|  |     g_print_enable = 1; | ||
|  |     iot_printf("ddr read...\n"); | ||
|  |     uint8_t instruction; | ||
|  |     uint32_t addr; | ||
|  |     uint32_t rdata0, rdata1; | ||
|  | 
 | ||
|  |     uint8_t w_inst; | ||
|  |     uint32_t w_addr; | ||
|  |     uint32_t wdata0; | ||
|  |     uint32_t wdata1; | ||
|  |     uint8_t w_lt; | ||
|  | 
 | ||
|  | #if MAC_PSRAM_DTEST == 0
 | ||
|  |     for(uint32_t i = 0; i<=4; i++) { | ||
|  |         instruction = 0x40; | ||
|  |         ddr_reg_read(instruction, i, &rdata0, &rdata1); | ||
|  |         iot_printf("==instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, i, rdata0, rdata1); | ||
|  |     } | ||
|  | #else
 | ||
|  |     REG32(0x50000008) |= 0x1; | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     for(uint32_t i = 0; i < 0xff; i++) { | ||
|  |         g_cache_data[i] = i; | ||
|  |     } | ||
|  |     uint32_t test_address = DDR_CACHE_PRIME_ADDR; | ||
|  |     if (test_address >= DDR_CACHE_PRIME_ADDR) { | ||
|  |         REG32(0x500000d8) |= 0x120000; | ||
|  |     } | ||
|  |     volatile uint8_t *reg = (volatile uint8_t *) test_address; | ||
|  |     //uint32_t test_address = 0xfff6000;
 | ||
|  |     //volatile uint8_t *reg = (volatile uint8_t *) test_address;
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     iot_printf("addr 0x%x: %08x\n", test_address, *reg); | ||
|  | 
 | ||
|  |     // write
 | ||
|  |     uint32_t len = DDR_CACHE_TEST_LENGTH; | ||
|  |     int i; | ||
|  |     uint8_t val = 0; | ||
|  |     uint8_t offset = 0; | ||
|  |     iot_printf("len: %d\n", len); | ||
|  | 
 | ||
|  | #if MAC_PSRAM_DTEST == 1
 | ||
|  |     start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if MCYCLE_ENA == 1
 | ||
|  |     mcycle_start = cpu_get_mcycle(); | ||
|  | #endif
 | ||
|  |     for(i = 0; i < len; i++) { | ||
|  |         val = g_cache_data[offset]; | ||
|  |         *(reg + i) = val; | ||
|  |         //*(reg+100) = val;
 | ||
|  |         offset++; | ||
|  |     } | ||
|  | #if MAC_PSRAM_DTEST == 1
 | ||
|  |     end = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |     cost = end- start; | ||
|  |     if (cost < 0) { // wrap around
 | ||
|  |         cost = (0x100000000LL) - start + end; | ||
|  |     } | ||
|  |     iot_printf("cost: %d\n", cost); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if MCYCLE_ENA == 1
 | ||
|  |     mcycle_end = cpu_get_mcycle(); | ||
|  |     mcycle_cost = mcycle_end - mcycle_start; | ||
|  |     iot_printf("cost: %d\n", mcycle_cost); | ||
|  | #endif
 | ||
|  |     // flush
 | ||
|  |     #if 1
 | ||
|  |     volatile uint32_t *dump = (volatile uint32_t *) test_address; | ||
|  |     iot_printf("offset 0 value: %08x\n", *(dump + 0x00000)); | ||
|  |     iot_printf("offset 1 value: %08x\n", *(dump + 0x4000)); | ||
|  |     iot_printf("offset 2 value: %08x\n", *(dump + 0x8000)); | ||
|  |     iot_printf("offset 3 value: %08x\n", *(dump + 0xc000)); | ||
|  |     iot_printf("offset 4 value: %08x\n", *(dump + 0x10000)); | ||
|  |     iot_printf("offset 0 value: %08x\n", *(dump + 0x00000)); | ||
|  |     #else
 | ||
|  |     ahb_cache_disable(); | ||
|  |     ahb_cache_enable(); | ||
|  |     ahb_cache_reset(); | ||
|  |     for(volatile uint32_t delay = 0; delay < 10000; delay++); | ||
|  |     #endif
 | ||
|  | 
 | ||
|  |     offset = 0; | ||
|  |     uint32_t err_cnt = 0; | ||
|  |     for(i = 0; i < len; i++) { | ||
|  |         val = g_cache_data[offset]; | ||
|  |         if(*(reg + i) != g_cache_data[offset]) { | ||
|  |             iot_printf("error1 i : %d, val: %02x, reg: %02x\n", | ||
|  |                     i, val, *(reg+i)); | ||
|  |             err_cnt++; | ||
|  |         } else { | ||
|  |             /*
 | ||
|  |             iot_printf("%02x ", *(reg+i)); | ||
|  |             if ( i % 4 == 3) { | ||
|  |                 iot_printf("\n"); | ||
|  |             } | ||
|  |             */ | ||
|  |         } | ||
|  |         offset++; | ||
|  |     } | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         iot_printf("test length %d, err length:%d\n", len, err_cnt); | ||
|  |     } | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         iot_printf("........\n"); | ||
|  |         iot_printf("ddr cache init finish..........\n"); | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         instruction = 0x40; | ||
|  |         addr = 0; | ||
|  |         rdata0 = 0x5a5a5a5a; | ||
|  |         rdata1 = 0x5a5a5a5a; | ||
|  | 
 | ||
|  |         iot_printf("write a reg\n"); | ||
|  |         w_inst = 0xc0; | ||
|  |         w_addr = 0; | ||
|  |         wdata0 = 0xffffffff; | ||
|  |         wdata1 = 0xffffffff; | ||
|  |         w_lt = 1; | ||
|  | 
 | ||
|  | 
 | ||
|  |         instruction = 0x40; | ||
|  |         addr = 4; | ||
|  |         rdata0 = 0; | ||
|  |         rdata1 = 0; | ||
|  |         w_inst = 0xc0; | ||
|  |         w_addr = 0; | ||
|  |         w_lt = 1; | ||
|  |         wdata0 = 0x01010101; | ||
|  |         wdata1 = 0x01010101; | ||
|  | 
 | ||
|  |         //volatile uint32_t *reg = (volatile uint32_t *)0x55228034;
 | ||
|  |         //*reg = 0x0100b0b1;
 | ||
|  |         ddr_reg_read(instruction, addr, &rdata0, &rdata1); | ||
|  |         iot_printf("\nread 1 instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, addr, rdata0, rdata1); | ||
|  | 
 | ||
|  |         if (g_write_en) { | ||
|  |             //*reg = 0x0100b0b1;
 | ||
|  |             ddr_reg_write(w_inst, w_addr, w_lt, wdata0, wdata1); | ||
|  |             iot_printf("\nwrite instr: %02x, addr: %08x, wdata0: %08x, wdata1: %08x\n", | ||
|  |                 w_inst, w_addr, wdata0, wdata1); | ||
|  |         } | ||
|  | 
 | ||
|  |         //*reg = 0x0100b0b1;
 | ||
|  |         ddr_reg_read(instruction, addr, &rdata0, &rdata1); | ||
|  |         iot_printf("\nread 2 instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, addr, rdata0, rdata1); | ||
|  | 
 | ||
|  |         /*
 | ||
|  |         instruction = 0x40; | ||
|  |         addr = 0; | ||
|  |         rdata0 = 0; | ||
|  |         rdata1 = 0; | ||
|  |         w_inst = 0xc0; | ||
|  |         w_addr = 4; | ||
|  |         w_lt = 1; | ||
|  |         wdata0 = 0x0; | ||
|  |         wdata1 = 0x0; | ||
|  |         ddr_reg_read(instruction, addr, &rdata0, &rdata1); | ||
|  |         iot_printf("\nread 1 instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, addr, rdata0, rdata1); | ||
|  | 
 | ||
|  |         if (g_write_en) { | ||
|  |             ddr_reg_write(w_inst, w_addr, w_lt, wdata0, wdata1); | ||
|  |             iot_printf("\nwrite instr: %02x, addr: %08x, wdata0: %08x, wdata1: %08x\n", | ||
|  |                 w_inst, w_addr, wdata0, wdata1); | ||
|  |         } | ||
|  | 
 | ||
|  |         ddr_reg_read(instruction, addr, &rdata0, &rdata1); | ||
|  |         iot_printf("\nread 2 instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, addr, rdata0, rdata1); | ||
|  |         */ | ||
|  | 
 | ||
|  |         for(uint32_t i = 0; i<=8; i++) { | ||
|  |             instruction = 0x40; | ||
|  |             ddr_reg_read(instruction, i, &rdata0, &rdata1); | ||
|  |             iot_printf("==instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, i, rdata0, rdata1); | ||
|  |         } | ||
|  |         iot_printf("===================\n\n"); | ||
|  | 
 | ||
|  |         /*
 | ||
|  |         iot_printf("read a reg\n"); | ||
|  |         ddr_reg_read(instruction, addr, &rdata0, &rdata1); | ||
|  |         iot_printf("\nread 2 instr: %02x, addr: %08x, rdata0: %08x, rdata1: %08x\n", | ||
|  |                 instruction, addr, rdata0, rdata1); | ||
|  |         */ | ||
|  |         // cfg : addr 0 val 01, addr 4 val 00, addr 01 val
 | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void k3d_ddr_test() | ||
|  | { | ||
|  |         uint32_t tmp; | ||
|  |     // prepare data
 | ||
|  |     /*
 | ||
|  |     volatile uint32_t *reg = (volatile uint32_t *) 0x73000000; | ||
|  | 
 | ||
|  |     *(reg) = 0x24aa2215; | ||
|  |     *(reg + 0x4) = *reg; | ||
|  |     *(reg + 0x100) = 0x78474633; | ||
|  |     *(reg + 0x101) = *(reg + 0x100); | ||
|  |     *(reg + 0xff) = *(reg + 0x100) - 1; | ||
|  |     *(reg + 0x200) = 0x55667788; | ||
|  |     *(reg + 0x201) = *(reg + 0x200); | ||
|  |     *(reg + 0x1ff) = *(reg + 0x200) - 1; | ||
|  |     *(reg + 0x300) = 0x99aabbcc; | ||
|  |     *(reg + 0x301) = *(reg + 0x300); | ||
|  |     *(reg + 0x2ff) = *(reg + 0x300) - 1; | ||
|  |     *(reg + 0x400) = 0x1235616; | ||
|  |     *(reg + 0x401) = *(reg + 0x400); | ||
|  |     *(reg + 0x3ff) = *(reg + 0x400) - 1; | ||
|  |     *(reg + 0x500) = 0x99aabbcc; | ||
|  |     *(reg + 0x501) = *(reg + 0x500); | ||
|  |     *(reg + 0x4ff) = *(reg + 0x500) - 1; | ||
|  |     *(reg + 0x600) = 0x21879654; | ||
|  |     *(reg + 0x601) = *(reg + 0x600); | ||
|  |     *(reg + 0x5ff) = *(reg + 0x600) - 1; | ||
|  |     *(reg + 0x700) = 0x1235616; | ||
|  |     *(reg + 0x701) = *(reg + 0x700); | ||
|  |     *(reg + 0x6ff) = *(reg + 0x700) - 1; | ||
|  |     *(reg + 0x800) = 0x78474633; | ||
|  |     *(reg + 0x801) = *(reg + 0x800); | ||
|  |     *(reg + 0x7ff) = *(reg + 0x800) - 1; | ||
|  |     */ | ||
|  |     #if 1
 | ||
|  |     volatile uint8_t *reg = (volatile uint8_t *) 0x73000000; | ||
|  | 
 | ||
|  |     for(uint32_t i = 0; i < 0xff; i++) { | ||
|  |         g_cache_data[i] = i; | ||
|  |     } | ||
|  | 
 | ||
|  |     // write
 | ||
|  |     uint32_t len = 1024 * 1024; | ||
|  |     int i; | ||
|  |     uint8_t val = 0; | ||
|  |     uint8_t offset = 0; | ||
|  |     iot_printf("len: %d\n", len); | ||
|  |     for(i = 0; i < len*4; i++) { | ||
|  |         val = g_cache_data[offset]; | ||
|  |         *(reg + i) = val; | ||
|  |         offset++; | ||
|  |     } | ||
|  | 
 | ||
|  |     for(i = 0; i < 0x10*4; i++) { | ||
|  |         *(reg + i + 0x10000) = 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG1_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_TRANS_LEN, tmp, len); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG2_ADDR); | ||
|  |     REG_FIELD_SET(AI_K3D_16L_LEN, tmp, 0x0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG2_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_RAM_SADDR_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_RAM_SADDR, tmp, 0x0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_RAM_SADDR_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_RAM_EADDR_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_RAM_EADDR, tmp, 0x1000); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_RAM_EADDR_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_DMC_SADDR0_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_DMC_SADDR0, tmp, 0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_DMC_SADDR0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_ST_ADDR); | ||
|  |     REG_FIELD_SET(K3D_OUT_RAM_EMP, tmp, 0x0); | ||
|  |     REG_FIELD_SET(K3D_OUT_RAM_FULL, tmp, 0x0); | ||
|  |     REG_FIELD_SET(K3D_OUT_RAM_RPTR, tmp, 0x0); | ||
|  |     REG_FIELD_SET(K3D_OUT_RAM_WPTR, tmp, 0x0); | ||
|  |     REG_FIELD_SET(DCAM_BIN_RAM_EMP, tmp, 0x0); | ||
|  |     REG_FIELD_SET(DCAM_BIN_RAM_FULL, tmp, 0x0); | ||
|  |     REG_FIELD_SET(DCAM_BIN_RAM_RPTR, tmp, 0x0); | ||
|  |     REG_FIELD_SET(DCAM_BIN_RAM_WPTR, tmp, 0x0); | ||
|  |     REG_FIELD_SET(AI_MST_DONE, tmp, 0x0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_ST_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_BURST_LEN, tmp, 64); | ||
|  |     REG_FIELD_SET(AI_MST_K3D_MODE, tmp, 0x0); | ||
|  |     REG_FIELD_SET(AI_MST_RW, tmp, 0x1); | ||
|  |     REG_FIELD_SET(AI_MST_ENA, tmp, 0x1); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         tmp = AI_GLB_READ_REG(CFG_AI_MST_ST_ADDR); | ||
|  | 
 | ||
|  |         if (tmp & 0x1) { | ||
|  |             iot_printf("write to ddr done...\n"); | ||
|  |             REG_FIELD_SET(AI_MST_ENA, tmp, 0x0); | ||
|  |             AI_GLB_WRITE_REG(CFG_AI_MST_CFG0_ADDR, tmp); | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     #endif
 | ||
|  |     // read data back
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG1_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_TRANS_LEN, tmp, 0x10); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG1_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_RAM_SADDR_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_RAM_SADDR, tmp, 0x10000); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_RAM_SADDR_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_RAM_EADDR_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_RAM_EADDR, tmp, 0x11000); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_RAM_EADDR_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_DMC_SADDR0_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_DMC_SADDR0, tmp, 0x0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_DMC_SADDR0_ADDR, tmp); | ||
|  | 
 | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_BURST_LEN, tmp, 64); | ||
|  |     REG_FIELD_SET(AI_MST_K3D_MODE, tmp, 0x0); | ||
|  |     REG_FIELD_SET(AI_MST_RW, tmp, 0x0); | ||
|  |     REG_FIELD_SET(AI_MST_ENA, tmp, 0x1); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  |     while(1) { | ||
|  |         tmp = AI_GLB_READ_REG(CFG_AI_MST_ST_ADDR); | ||
|  | 
 | ||
|  |         if (tmp & 0x1) { | ||
|  |             iot_printf("read to ddr done...\n"); | ||
|  |             REG_FIELD_SET(AI_MST_ENA, tmp, 0x0); | ||
|  |             AI_GLB_WRITE_REG(CFG_AI_MST_CFG0_ADDR, tmp); | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     tmp = AI_GLB_READ_REG(CFG_AI_MST_CFG0_ADDR); | ||
|  |     REG_FIELD_SET(AI_MST_ENA, tmp, 0x0); | ||
|  |     AI_GLB_WRITE_REG(CFG_AI_MST_CFG0_ADDR, tmp); | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t g_test_mode = 0;    // 0: cache mode, 1: k3d mode
 | ||
|  | int main(void) | ||
|  | { | ||
|  |     dbg_uart_init(); | ||
|  | 
 | ||
|  |     iot_printf("\n-------DDR TEST---------\n"); | ||
|  |     if (g_test_mode) { | ||
|  |         iot_printf("k3d mode test start\n"); | ||
|  |         k3d_ddr_test(); | ||
|  |         iot_printf("end.............\n"); | ||
|  |     } else { | ||
|  |         iot_printf("k3d mode test start\n"); | ||
|  | #if MAC_PSRAM_DTEST == 0
 | ||
|  |         ddr_module_cache_cfg(); | ||
|  | #endif
 | ||
|  |         ddr_module_test(); | ||
|  |     } | ||
|  |     //ai_ref_compare_test();
 | ||
|  |     iot_printf("\n\n"); | ||
|  | 
 | ||
|  |     while(1); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } |