334 lines
11 KiB
C
334 lines
11 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 "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);
|
|
}
|