Files
kunlun/dtest/dtest3/kl3_smc_test/smc_main.c

379 lines
11 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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 "hw_reg_api.h"
#include "chip_reg_base.h"
#include "apb_cache_reg.h"
#include "sram.h"
#include "smc.h"
#include "ahb.h"
#include "gp_timer.h"
#include "uart.h"
#include "dbg_io.h"
#include "iot_io_api.h"
#include "os_mem_api.h"
#include "iot_errno_api.h"
#include "dtest_printf.h"
#define DTEST_SMC_CASE_GET_SIZE (1 << 0)
#define DTEST_SMC_CASE_API_RW (1 << 1)
#define DTEST_SMC_CASE_CACHE_RW (1 << 2)
#define DTEST_SMC_CASE_FULL_RW (1 << 3)
/* test PSRAM size using write loopback mechanism */
uint32_t dtest_smc_get_psram_size_test(uint8_t *size)
{
uint8_t i;
uint32_t addr_test, data_test, data;
dcase_start("get psram size test\n");
// cache_invalidate(0, ICACHE0_SMC_RAM_BASEADDR, 32);
cache_clear(0);
*(volatile uint32_t *)(ICACHE0_SMC_RAM_BASEADDR) = 0x0;
cache_flush(0, 0x00, 32);
for (i = 0; i < 32; i++) {
addr_test = 0x100000 * i;
uint8_t temp = i ^ 0x55;
data_test = (temp << 24) | (temp << 16) | (temp << 8) | temp;
dprintf("test addr:0x%08x, data:0x%08x\n", addr_test, data_test);
*(volatile uint32_t *)(ICACHE0_SMC_RAM_BASEADDR + addr_test) = data_test;
cache_flush(0, addr_test, 32);
// cache_invalidate(0, ICACHE0_SMC_RAM_BASEADDR, 32);
cache_clear(0);
data = *(volatile uint32_t *)(ICACHE0_SMC_RAM_BASEADDR);
if (addr_test == 0x00) {
if (data != data_test) {
dprintf("addr(0x00) write and read error, psram not working\n");
*size = 0;
break;
}
} else {
if (data == data_test) {
dprintf("write data loopback\n");
break;
}
}
}
if (i == 32) {
dprintf("no matching psram size found\n");
goto fail;
}
dprintf("get psram size:%d\n", i);
dcase_success();
return ERR_OK;
fail:
dcase_failed();
return ERR_FAIL;
}
uint32_t dtest_smc_api_test()
{
int i = 0;
uint8_t rdata[0x40] = {0};
uint8_t wdata[0x40] = {0};
uint8_t data_test = 0x55;
uint32_t addr_test = 0x10000;
dcase_start("smc api read/write test\n");
dprintf("init test data with 0x%x\n", data_test);
os_mem_set(wdata, data_test, sizeof(wdata));
while(sram_qspi_is_busy() != HAL_SRAM_OK) {
dprintf("FLASH IS Busy Now!\n");
}
/* spi mode */
dprintf("use spi mode to read/write psram\n");
sram_qspi_exit();
while (sram_qspi_is_busy() != HAL_SRAM_OK);
dprintf("qpi exit succeed\n");
dprintf("spi write data\n");
sram_qspi_write(wdata, addr_test, sizeof(wdata));
while(sram_qspi_is_busy() != HAL_SRAM_OK);
dprintf("spi read data\n");
sram_qspi_read(rdata, addr_test, sizeof(rdata));
while(sram_qspi_is_busy() != HAL_SRAM_OK);
for (i = 0; i < sizeof(wdata); i++) {
if (wdata[i] != rdata[i]) {
dprintf("spi mode read data err, index:%d, wdata:%x, rdata:%x\n", i, wdata[i], rdata[i]);
goto fail;
}
}
/* qpi mode */
data_test = 0xaa;
dprintf("use qpi mode to read/write psram, init test data with 0x%x\n", data_test);
os_mem_set(wdata, data_test, sizeof(wdata));
sram_qspi_enter();
while(sram_qspi_is_busy() != HAL_SRAM_OK);
dprintf("qspi enter succeed\n");
dprintf("qpi write data\n");
sram_qspi_quad_write(wdata, addr_test, sizeof(wdata));
while(sram_qspi_is_busy());
dprintf("qpi read data\n");
os_mem_set(rdata, 0x00, sizeof(rdata));
sram_qspi_quad_read(rdata, addr_test, sizeof(rdata));
while(sram_qspi_is_busy() != HAL_SRAM_OK);
for (i = 0; i < sizeof(wdata); i++) {
if (wdata[i] != rdata[i]) {
dprintf("qpi mode read data err, index:%d, wdata:%x, rdata:%x\n", i, wdata[i], rdata[i]);
goto fail;
}
}
dcase_success();
return ERR_OK;
fail:
dcase_failed();
return ERR_FAIL;
}
uint32_t dtest_smc_cache_rw_test()
{
uint32_t i = 0, data = 0, error = 0, test_len = 0x1000, addr_test = 0x000000;
dcase_start("smc cache read/write test\n");
for (i = 0; i < test_len; i++) {
*((volatile uint8_t*)(DCACHE0_SMC_RAM_BASEADDR + addr_test + i)) = i % 0xff;
}
cache_flush(AHB_CACHE_D0, addr_test, test_len);
dprintf("write/read sram by icache0\n");
cache_invalidate(AHB_CACHE_I0, addr_test, test_len);
for (i = 0; i < test_len; i++) {
data = *(volatile uint8_t *)(ICACHE0_SMC_RAM_BASEADDR + addr_test + i);
if (data != (i % 0xff)) {
dprintf("ERROR icache0 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
dprintf("write/read sram by icache1\n");
cache_invalidate(AHB_CACHE_I1, addr_test, test_len);
for (i = 0; i < test_len; i++) {
data = *(volatile uint8_t *)(ICACHE1_SMC_RAM_BASEADDR + addr_test + i);
if (data != (i % 0xff)) {
dprintf("ERROR icache1 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
dprintf("write/read sram by icache2\n");
cache_invalidate(AHB_CACHE_I2, addr_test, test_len);
for (i = 0; i < test_len; i++) {
data = *(volatile uint8_t *)(ICACHE2_SMC_RAM_BASEADDR + addr_test + i);
if (data != (i % 0xff)) {
dprintf("ERROR icache2 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
dprintf("write/read sram by dcache0\n");
cache_invalidate(AHB_CACHE_D0, addr_test, test_len);
for (i = 0; i < test_len; i++) {
data = *(volatile uint8_t *)(DCACHE0_SMC_RAM_BASEADDR + addr_test + i);
if (data != (i % 0xff)) {
dprintf("ERROR dcache0 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
dprintf("write/read sram by dcache1\n");
cache_invalidate(AHB_CACHE_D1, addr_test, test_len);
for (i = 0; i < test_len; i++) {
data = *(volatile uint8_t *)(DCACHE1_SMC_RAM_BASEADDR + addr_test + i);
if (data != (i % 0xff)) {
dprintf("ERROR dcache1 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
if (0 == error) {
dcase_success();
return ERR_OK;
}else {
dcase_failed();
return ERR_FAIL;
}
}
uint32_t dtest_smc_psram_full_rw_test(uint8_t psram_size)
{
uint32_t i = 0, error = 0, temp;
uint8_t data_test = 0x55, data;
uint32_t len_test = psram_size * 0x100000;
uint32_t time_old = 0, time_new = 0, time_use;
dcase_start("psram full read/write test\n");
/* icache_wr_auto_load = 0, it can significantly speed up the reading and
* writing of large amounts of data.
* In this test, the cache has no other work, and almost no miss will
* be generated, so no significant reduction in time is observed(4m - 14678us).
*/
temp = CACHE0_READ_REG(CFG_CACHE_CTR0_ADDR);
REG_FIELD_SET(ICACHE_WR_AUTO_LOAD, temp, 0);
CACHE0_WRITE_REG(CFG_CACHE_CTR0_ADDR, temp);
time_old = gp_timer_get_current_val(0);
dprintf("write psram, data:0x%x, len:0x%x\n", data_test, len_test);
cache_clear(AHB_CACHE_I0);
for (i = 0; i < len_test; i++) {
*((volatile uint8_t*)(ICACHE0_SMC_RAM_BASEADDR + i)) = i % 0xff;
}
dprintf("read psram\n");
cache_invalidate(AHB_CACHE_I0, 0x00, 0x8000);
for (i = 0; i < len_test; i++) {
data = *(volatile uint8_t *)(ICACHE0_SMC_RAM_BASEADDR + i);
if (data != data_test) {
dprintf("ERROR icache0 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
data_test = 0xaa;
dprintf("write psram, data:0x%x, len:0x%x\n", data_test, len_test);
cache_clear(AHB_CACHE_I0);
for (i = 0; i < len_test; i++) {
*((volatile uint8_t*)(ICACHE0_SMC_RAM_BASEADDR + i)) = i % 0xff;
}
dprintf("read psram\n");
cache_invalidate(AHB_CACHE_I0, 0x00, 0x8000);
for (i = 0; i < len_test; i++) {
data = *(volatile uint8_t *)(ICACHE0_SMC_RAM_BASEADDR + i);
if (data != data_test) {
dprintf("ERROR icache0 sram read: i:%d, data:%02x\n", i, data);
error++;
}
}
time_new = gp_timer_get_current_val(0);
time_use = (time_old < time_new) ? (time_new - time_old) :
(0xffffffff - time_old + time_new);
dprintf("full read/write complete, it takes %d us\n", time_use);
temp = CACHE0_READ_REG(CFG_CACHE_CTR0_ADDR);
REG_FIELD_SET(ICACHE_WR_AUTO_LOAD, temp, 1);
CACHE0_WRITE_REG(CFG_CACHE_CTR0_ADDR, temp);
if (0 == error) {
dcase_success();
return ERR_OK;
}else {
dcase_failed();
return ERR_FAIL;
}
}
void dtest_smc_main()
{
uint32_t case_group = 0, error_cnt = 0;
uint8_t psram_size = 0;
dbg_uart_init();
dconfig();
dstart();
dversion();
if (dtest_get_case_group(&case_group) < 0) {
case_group = 0xffffffff;
}
dprintf("get case group:0x%08X\n", case_group);
gp_timer_init();
gp_timer_set(0, 0xffffffff, 0);
gp_timer_start(0);
/* reset emc */
dprintf("reset emc\n");
ahb_emc_disable();
ahb_emc_enable();
ahb_emc_reset();
/* init psram */
dprintf("initialize psram\n");
sram_qspi_init();
sram_qspi_enter();
hal_smc_qspi_quad_cfg(0);
/* init cache */
dprintf("initialize all of the cache\n");
for (uint8_t i = AHB_CACHE_I0; i < AHB_CACHE_MAX; i++) {
cache_disable(i);
cache_enable(i);
cache_fill_valid_space(i);
}
if (case_group & DTEST_SMC_CASE_GET_SIZE) {
if (dtest_smc_get_psram_size_test(&psram_size)) {
error_cnt++;
}
}
/* only buffer mode, register mode will be failed */
if (case_group & DTEST_SMC_CASE_API_RW) {
if (dtest_smc_api_test()) {
error_cnt++;
}
}
if (case_group & DTEST_SMC_CASE_CACHE_RW) {
if (dtest_smc_cache_rw_test()) {
error_cnt++;
}
}
if (case_group & DTEST_SMC_CASE_FULL_RW) {
if (dtest_smc_psram_full_rw_test(psram_size)) {
error_cnt++;
}
}
if (error_cnt) {
dprintf("smc dtest failed\n");
} else {
dprintf("smc dtest succeed\n");
}
dend();
}
int main(void) {
dtest_smc_main();
return 0;
}