Files
2024-09-28 14:24:04 +08:00

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