/**************************************************************************** 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 "ahb_rf.h" // ############################################################################ // common define #define REG32(a) (*((volatile uint32_t *)(a))) // common define end // ############################################################################ // ############################################################################ // ddr define #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) typedef enum ddr_dev_x8_x16_mode { DEV_X8_MODE = 0, DEV_X16_MODE = 1, }ddr_dev_x8_x16_mode_t; // ddr define end 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 data 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, 2^n, unit is bit 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 = AHB_RF_READ_REG(CFG_AHB_CTR0_ADDR); REG_FIELD_SET(ICACHE_DMC_MODE, tmp, 1); REG_FIELD_SET(DCACHE_DMC_MODE, tmp, 1); AHB_RF_WRITE_REG(CFG_AHB_CTR0_ADDR, tmp); // set space tmp = AHB_RF_READ_REG(CFG_CACHE_VALID_SPACE_ADDR); REG_FIELD_SET(SMC_SPACE, tmp, 0x10); REG_FIELD_SET(SFC_SPACE, tmp, 4); AHB_RF_WRITE_REG(CFG_CACHE_VALID_SPACE_ADDR, tmp); }