This commit is contained in:
刘可亮
2024-10-30 16:50:31 +08:00
parent 0ef85b55da
commit 661e71562d
458 changed files with 46555 additions and 12133 deletions

View File

@@ -1,9 +1,2 @@
# Luban-Lite SDK
Luban-Lite 是 ArtInChip 针对 RTOS 领域开发的一套 SDK。
相关帮助文档如下:
- [用户使用指南_Linux环境](doc/luban-lite_user_guid_linux.md)
- [用户使用指南_Windows环境](doc/luban-lite_user_guid_windows.md)
- [驱动开发指南](doc/luban-lite_driver_development_guid.md)

View File

@@ -1,3 +1,39 @@
# V1.1.1 #
## 新增 ##
- FreeTypeD13x支持独立使用PSRAM Heap
- MPP支持FLAC的Audio封装格式
- USB Display增加Linux Host端的驱动安装包
- Camera框架增加更多的摄像头调节接口GM7150支持调整色度
- 打包支持自动计算NFTL分区的镜像大小
- Benchmark支持单精度浮点的模式
- 新增示例test_camera
- I2C新增软件模拟I2C的驱动实现
- G73x支持栈回溯功能
- Touch框架中支持翻转、旋转、缩放、裁剪目前已适配GT911
- 新增方案G73x scan
- 新增器件:
- NANDXT26G02D
## 优化 ##
- Boot自动计算BootLoader的size信息默认将其放在PSRAM的末尾
- MPP优化第一次播放时的噪声处理
- GMAC优化内存资源的占用
- USB Display优化Touch的同步处理OSD对屏幕分辨率自适应支持屏幕有效区域的裁剪
- WiFiRTL完善功能支持
- test_dvp & UVC优化调试log中的信息描述提升易读性
- 启动动画:优化内存资源占用;支持 480x272 小分辨率的屏幕
- LVGL V9优化多处资源管理和处理性能支持图片cache的大小配置
## 修改 ##
- LVGL V9默认关闭性能监测支持导出Framebuffer完善绘画Buf的处理支持从SD卡中读取RTP配置
- AWTK修正第一帧的vsync处理
- DE修正CCM、GAMMA参数
- Audio调整AMIC的默认配置参数
- 启动动画:修正动画过程中的图片切换同步
- LittleFS、PSADC修正打开 RT_DEBUG 后的编译问题
- 修正colorblock在屏幕裁剪模式中的越界问题
- 修正同时播放视频时的画面撕裂问题
# V1.1.0 #
## 新增 ##
- 支持LVGL9并适配了所有Demo

View File

@@ -263,6 +263,16 @@ config LV_CACHE_IMG_NUM
default 2
depends on LPKG_USING_LVGL
config LV_CACHE_DEF_SIZE
hex "LVGL image cached size"
default 0x800000
depends on LVGL_V_9
config LV_IMAGE_HEADER_CACHE_DEF_CNT
int "LVGL image header cached number"
default 20
depends on LVGL_V_9
config LV_DISPLAY_ROTATE_EN
bool "LVGL enable display rotation"
default n
@@ -294,6 +304,21 @@ config LV_ROTATE_DEGREE
default 180 if LV_ROTATE_180
default 270 if LV_ROTATE_270
config MPP_JPEG_DEC_OUT_SIZE_LIMIT_ENABLE
bool "Limit the output size of MPP JPEG decoder"
default n
depends on LPKG_USING_LVGL
if MPP_JPEG_DEC_OUT_SIZE_LIMIT_ENABLE
config MPP_JPEG_DEC_MAX_OUT_WIDTH
int "Max output width of MPP JPEG decoder"
default 2048
config MPP_JPEG_DEC_MAX_OUT_HEIGHT
int "Max output height of MPP JPEG decoder"
default 2048
endif
# Parameters for LVGL meter demo
if AIC_LVGL_METER_DEMO
config LV_METER_SIMPLE_POINT

View File

@@ -8,18 +8,25 @@ config AIC_BOOTLOADER
select AIC_USING_UMM_HEAP
menu "Memory"
config AIC_BOOTLOADER_MEM_AUTO
bool "Bootloader memory auto config"
default y
config AIC_BOOTLOADER_TEXT_BASE
hex "BootLoader link address"
default 0
depends on !AIC_BOOTLOADER_MEM_AUTO
config AIC_BOOTLOADER_TEXT_SIZE
hex "BootLoader code memory size"
default 0
default 0x3FF00
config AIC_BOOTLOADER_HEAP_BASE
hex "BootLoader heap address"
default 0
depends on !AIC_BOOTLOADER_MEM_AUTO
config AIC_BOOTLOADER_HEAP_SIZE
hex "BootLoader heap size"
default 0
default 0xC0000
endmenu
menu "Console"

View File

@@ -544,7 +544,9 @@ err:
static void do_brom_upg(void)
{
#ifdef AIC_WRI_DRV
aic_set_reboot_reason(REBOOT_REASON_UPGRADE);
#endif
reboot_device();
}

View File

@@ -190,11 +190,12 @@ static bool force_upg_check(void)
int upg_type_check(enum boot_device bd)
{
enum aic_reboot_reason r;
upg_type = UPG_TYPE_NONE;
upg_mode = UPG_MODE_NORMAL;
#ifdef AIC_WRI_DRV
enum aic_reboot_reason r;
r = aic_get_reboot_reason();
/*
* if REBOOT_REASON_UPGRADE is not clear in BROM or PBP, should be clear
@@ -218,6 +219,7 @@ int upg_type_check(enum boot_device bd)
aic_clr_reboot_reason();
return 0;
}
#endif
if (bd == BD_USB) {
if (usbd_connect_pc_check()) {

View File

@@ -26,7 +26,7 @@
#define WIDTH_SPLIT_NUMERATOR 5
#define WIDTH_SPLIT_DENOMINATOR 6
#define BAR_HEIGHT 35
#define BAR_HEIGHT 32
#define SPLIT_WIDTH(w) \
((w) * WIDTH_SPLIT_NUMERATOR / WIDTH_SPLIT_DENOMINATOR)
@@ -139,13 +139,11 @@ void aicfb_draw_rect(struct aicfb_screeninfo *info,
u8 red, u8 green, u8 blue)
{
#ifndef AIC_BOOTLOADER_CMD_ONLY_FB_CONSOLE
unsigned long dcache_size, fb_dcache_start;
int pbytes = info->bits_per_pixel / 8;
unsigned char *fb;
int i, j;
fb = (unsigned char *)(info->framebuffer + y * info->stride + x * pbytes);
fb_dcache_start = ALIGN_DOWM((unsigned long)fb, ARCH_DMA_MINALIGN);
switch (info->format) {
case MPP_FMT_ARGB_8888:
@@ -183,9 +181,7 @@ void aicfb_draw_rect(struct aicfb_screeninfo *info,
return;
};
dcache_size = ALIGN_UP((unsigned long)fb - fb_dcache_start,
ARCH_DMA_MINALIGN);
aicos_dcache_clean_range((unsigned long *)fb_dcache_start, dcache_size);
aicos_dcache_clean_range((unsigned long *)info->framebuffer, info->smem_len);
#endif
}
@@ -293,7 +289,7 @@ void aicfb_draw_bar(unsigned int value)
#if (AIC_BOOTLOADER_CMD_PROGRESS_BAR_ROTATE == 90)
width = BAR_HEIGHT;
height = SPLIT_WIDTH(info.height);
bar_x = (info.width - width) / 2;
bar_x = 0;
bar_y = (info.height - height) / 2 + height;
console_x = bar_x + BAR_HEIGHT + 5;
console_y = info.height / 2;
@@ -301,7 +297,7 @@ void aicfb_draw_bar(unsigned int value)
width = SPLIT_WIDTH(info.width);
height = BAR_HEIGHT;
bar_x = (info.width - width) / 2;
bar_y = (info.height - height) / 2;
bar_y = 0;
console_x = info.width / 2;
console_y = bar_y + BAR_HEIGHT + 5;
#endif

View File

@@ -137,6 +137,9 @@ int aicupg_fat_direct_write(char *dst_type, u32 intf_id, char *fpath,
typedef void (*progress_cb)(u32 percent);
void aicupg_fat_set_process_cb(progress_cb cb);
void *aicupg_malloc_align(u32 size, size_t align);
void aicupg_free_align(void *ptr);
#ifdef __cplusplus
}
#endif

View File

@@ -605,7 +605,7 @@ static s32 get_mem_buf_cmd_read_output_data(struct upg_cmd *cmd, u8 *buf,
if (cmd->state == CMD_STATE_RESP) {
memlen = (u32)(long)cmd->priv;
mem = aicos_malloc_align(0, memlen, ARCH_DMA_MINALIGN);
mem = aicupg_malloc_align(memlen, ARCH_DMA_MINALIGN);
/*
* Enter read RESP state, to make it simple, HOST should read
* RESP in one read operation.
@@ -669,7 +669,7 @@ static s32 free_mem_buf_cmd_write_input_data(struct upg_cmd *cmd, u8 *buf,
memcpy(&addr, buf, 4);
clen += 4;
aicos_free_align(0, (void *)(long)addr);
aicupg_free_align((void *)(long)addr);
cmd_state_set_next(cmd, CMD_STATE_RESP);
}

View File

@@ -138,7 +138,7 @@ s32 mmc_fwc_sparse_fill(struct aicupg_mmc_priv *priv, struct aic_partition *part
u32 *fill_buf, fill_buf_num_blks, fill_blks = 0;
int i, j;
fill_buf = (u32 *)aicos_malloc_align(0, ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE), CACHE_LINE_SIZE);
fill_buf = (u32 *)aicupg_malloc_align(ROUNDUP(SPARSE_FILLBUF_SIZE, CACHE_LINE_SIZE), CACHE_LINE_SIZE);
if (!fill_buf) {
pr_err("Malloc failed for: CHUNK_TYPE_FILL\n");
return 0;
@@ -193,7 +193,7 @@ s32 mmc_fwc_sparse_fill(struct aicupg_mmc_priv *priv, struct aic_partition *part
}
out:
aicos_free_align(0, fill_buf);
aicupg_free_align(fill_buf);
return fill_blks;
}
@@ -404,7 +404,7 @@ s32 mmc_fwc_raw_write(struct fwc_info *fwc, u8 *buf, s32 len)
long n;
u32 clen = 0, calc_len = 0;
rdbuf = aicos_malloc_align(0, len, CACHE_LINE_SIZE);
rdbuf = aicupg_malloc_align(len, CACHE_LINE_SIZE);
if (!rdbuf) {
pr_err("Error: malloc buffer failed.\n");
return 0;
@@ -468,7 +468,7 @@ s32 mmc_fwc_raw_write(struct fwc_info *fwc, u8 *buf, s32 len)
out:
if (rdbuf)
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return clen;
}

View File

@@ -205,7 +205,7 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
int total_len = 0, remain_offset = 0;
u8 *wbuf = NULL, *pbuf = NULL;
wbuf = aicos_malloc_align(0, ROUNDUP(len, fwc->block_size), CACHE_LINE_SIZE);
wbuf = aicupg_malloc_align(ROUNDUP(len, fwc->block_size), CACHE_LINE_SIZE);
if (!wbuf) {
pr_err("malloc failed.\n");
return 0;
@@ -293,13 +293,13 @@ s32 nand_fwc_uffs_write(struct fwc_info *fwc, u8 *buf, s32 len)
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
fwc->calc_partition_crc = fwc->meta.crc;
aicos_free_align(0, wbuf);
aicupg_free_align(wbuf);
return len;
out:
if (wbuf)
aicos_free_align(0, wbuf);
aicupg_free_align(wbuf);
return ret;
}
@@ -350,7 +350,7 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
int i, ret = 0, calc_len = 0;
u8 *rdbuf, *buf_to_write, *buf_to_read;
rdbuf = aicos_malloc_align(0, len, CACHE_LINE_SIZE);
rdbuf = aicupg_malloc_align(len, CACHE_LINE_SIZE);
if (!rdbuf) {
pr_err("Error: malloc buffer failed.\n");
return 0;
@@ -431,11 +431,11 @@ s32 nand_fwc_mtd_write(struct fwc_info *fwc, u8 *buf, s32 len)
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return len;
out:
if (rdbuf)
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return 0;
}
@@ -449,7 +449,7 @@ s32 nand_fwc_nftl_write(struct fwc_info *fwc, u8 *buf, s32 len)
int i, calc_len = 0, ret = 0;
u8 *rdbuf;
rdbuf = aicos_malloc_align(0, len, CACHE_LINE_SIZE);
rdbuf = aicupg_malloc_align(len, CACHE_LINE_SIZE);
if (!rdbuf) {
pr_err("Error: malloc buffer failed.\n");
return 0;
@@ -514,11 +514,11 @@ s32 nand_fwc_nftl_write(struct fwc_info *fwc, u8 *buf, s32 len)
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
(void)ret;
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return len;
out:
if (rdbuf)
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return 0;
}
#endif
@@ -567,6 +567,9 @@ void nand_fwc_data_end(struct fwc_info *fwc)
if (!priv)
return;
if (priv->spl_flag)
nand_fwc_spl_end(priv);
#ifdef AIC_NFTL_SUPPORT
struct nftl_api_handler_t *nftl_handler;
for (int i = 0; i < MAX_DUPLICATED_PART; i++) {

View File

@@ -683,6 +683,17 @@ s32 nand_fwc_spl_write(struct fwc_info *fwc, u8 *buf, s32 len)
return len;
}
s32 nand_fwc_spl_end(struct aicupg_nand_priv *priv)
{
struct aicupg_nand_spl *spl;
spl = &g_nand_spl;
if (spl->image_buf)
free(spl->image_buf);
return 0;
}
int nand_spl_get_candidate_blocks(u32 *blks, u32 size)
{
if (!blks || size < SPL_CANDIDATE_BLOCK_NUM) {

View File

@@ -87,6 +87,7 @@ s32 nand_fwc_spl_reserve_blocks(struct aicupg_nand_priv *priv);
s32 nand_fwc_spl_prepare(struct aicupg_nand_priv *priv, u32 datasiz,
u32 blksiz);
s32 nand_fwc_spl_write(struct fwc_info *fwc, u8 *buf, s32 len);
s32 nand_fwc_spl_end(struct aicupg_nand_priv *priv);
int nand_spl_get_candidate_blocks(u32 *blks, u32 size);
#ifdef __cplusplus

View File

@@ -137,7 +137,7 @@ s32 nor_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
int i, calc_len = 0, ret = 0;
u8 *rdbuf;
rdbuf = aicos_malloc_align(0, len, CACHE_LINE_SIZE);
rdbuf = aicupg_malloc_align(len, CACHE_LINE_SIZE);
if (!rdbuf) {
pr_err("Error: malloc buffer failed.\n");
return 0;
@@ -201,12 +201,12 @@ s32 nor_fwc_data_write(struct fwc_info *fwc, u8 *buf, s32 len)
fwc->trans_size += len;
pr_debug("%s, data len %d, trans len %d\n", __func__, len, fwc->trans_size);
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return len;
out:
if (rdbuf)
aicos_free_align(0, rdbuf);
aicupg_free_align(rdbuf);
return ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Artinchip Technology Co., Ltd
* Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -59,10 +59,10 @@ s32 trans_layer_rw_proc(struct phy_data_rw *rw, u8 *buffer, u32 len)
if (!trans_pkt_buf) {
trans_pkt_siz = TRANS_DATA_BUFF_MAX_SIZE;
trans_pkt_buf = aicos_malloc_align(0, trans_pkt_siz, CACHE_LINE_SIZE);
trans_pkt_buf = aicupg_malloc_align(trans_pkt_siz, CACHE_LINE_SIZE);
if (!trans_pkt_buf) {
trans_pkt_siz = TRANS_DATA_BUFF_MIN_SIZE;
trans_pkt_buf = aicos_malloc_align(0, trans_pkt_siz, CACHE_LINE_SIZE);
trans_pkt_buf = aicupg_malloc_align(trans_pkt_siz, CACHE_LINE_SIZE);
if (!trans_pkt_buf) {
pr_err("malloc trans pkt buf(%u) failed.\n", trans_pkt_siz);
return -1;

View File

@@ -33,21 +33,21 @@ static void *upg_fat_malloc_align(struct fwc_info *fwc, u32 *size, size_t align)
switch (*size) {
case DATA_WRITE_ONCE_MAX_SIZE:
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MAX_SIZE, fwc->block_size);
ptr = aicos_malloc_align(0, *size, align);
ptr = aicupg_malloc_align(*size, align);
if (ptr)
break;
case DATA_WRITE_ONCE_MID_SIZE:
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MID_SIZE, fwc->block_size);
ptr = aicos_malloc_align(0, *size, align);
ptr = aicupg_malloc_align(*size, align);
if (ptr)
break;
case DATA_WRITE_ONCE_MIN_SIZE:
*size = ALIGN_DOWN(DATA_WRITE_ONCE_MIN_SIZE, fwc->block_size);
ptr = aicos_malloc_align(0, *size, align);
ptr = aicupg_malloc_align(*size, align);
if (ptr)
break;
default:
ptr = aicos_malloc_align(0, *size, align);
ptr = aicupg_malloc_align(*size, align);
if (ptr)
break;
}
@@ -57,7 +57,7 @@ static void *upg_fat_malloc_align(struct fwc_info *fwc, u32 *size, size_t align)
static void upg_fat_free_align(void *mem)
{
aicos_free_align(0, mem);
aicupg_free_align(mem);
}
#define FRAME_LIST_SIZE 4096
@@ -73,7 +73,7 @@ static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
fwc = NULL;
buf = NULL;
fwc = aicos_malloc_align(0, sizeof(struct fwc_info), FRAME_LIST_SIZE);
fwc = aicupg_malloc_align(sizeof(struct fwc_info), FRAME_LIST_SIZE);
if (!fwc) {
pr_err("Error: malloc fwc failed.\n");
ret = -1;
@@ -91,7 +91,7 @@ static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
media_data_write_start(fwc);
/*config write size once*/
if (config_ram_size <= 0x100000)
if (config_ram_size <= 0x400000)
write_once_size = DATA_WRITE_ONCE_MIN_SIZE;
else
write_once_size = DATA_WRITE_ONCE_MAX_SIZE;
@@ -151,7 +151,7 @@ static s32 media_device_write(char *image_name, struct fwc_meta *pmeta)
(total_len * 1000000 / start_us) / 1024 % 1024);
upg_fat_free_align(buf);
aicos_free_align(0, fwc);
aicupg_free_align(fwc);
return total_len;
err:
@@ -159,7 +159,7 @@ err:
if (buf)
upg_fat_free_align(buf);
if (fwc)
aicos_free_align(0, fwc);
aicupg_free_align(fwc);
return 0;
}
@@ -175,7 +175,7 @@ s32 aicupg_fat_write(char *image_name, char *protection,
u64 total_len = 0;
pmeta = NULL;
pmeta = (struct fwc_meta *)aicos_malloc_align(0, header->meta_size, FRAME_LIST_SIZE);
pmeta = (struct fwc_meta *)aicupg_malloc_align(header->meta_size, FRAME_LIST_SIZE);
if (!pmeta) {
pr_err("Error: malloc for meta failed.\n");
ret = -1;
@@ -231,10 +231,10 @@ s32 aicupg_fat_write(char *image_name, char *protection,
(ulong)((total_len * 1000000 / start_us) / 1024 / 1024),
(ulong)((total_len * 1000000 / start_us) / 1024 % 1024));
aicos_free_align(0, pmeta);
aicupg_free_align(pmeta);
return write_len;
err:
if (pmeta)
aicos_free_align(0, pmeta);
aicupg_free_align(pmeta);
return 0;
}

View File

@@ -28,7 +28,7 @@ static int fat_direct_mmc_write_raw(struct aic_sdmc *host, char *fpath,
printf("Programming %s to 0x%x\n", fpath, doffset);
printf("\t");
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
soffset = 0;
writecnt = 0;
@@ -62,7 +62,7 @@ static int fat_direct_mmc_write_raw(struct aic_sdmc *host, char *fpath,
}
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
printf("\n");
return ret;
}
@@ -79,7 +79,7 @@ static int fat_direct_mmc_write_sparse(struct aic_sdmc *host, char *fpath,
printf("Programming %s to 0x%x\n", fpath, doffset);
printf("\t");
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
soffset = 0;
dolen = MAX_WRITE_SIZE;
@@ -149,8 +149,8 @@ static int fat_direct_mmc_write_sparse(struct aic_sdmc *host, char *fpath,
/* Read raw chunk data */
if (chunk_data_sz > MAX_WRITE_SIZE) {
aicos_free_align(0, buf);
buf = aicos_malloc_align(0, chunk_data_sz, FRAME_LIST_SIZE);
aicupg_free_align(buf);
buf = aicupg_malloc_align(chunk_data_sz, FRAME_LIST_SIZE);
p = buf;
}
@@ -225,7 +225,7 @@ static int fat_direct_mmc_write_sparse(struct aic_sdmc *host, char *fpath,
out:
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
printf("\n");
return ret;
}

View File

@@ -65,7 +65,7 @@ static int fat_direct_spinand_write_boot(char *fpath, struct mtd_dev *mtd)
return -1;
}
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
soffset = 0;
while (1) {
actread = 0;
@@ -91,7 +91,7 @@ static int fat_direct_spinand_write_boot(char *fpath, struct mtd_dev *mtd)
}
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
return 0;
}
@@ -103,7 +103,7 @@ static int fat_direct_spinand_write_data(char *fpath, struct mtd_dev *mtd,
u32 soffset;
ulong dolen, actread, writecnt;
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
soffset = 0;
writecnt = 0;
@@ -155,7 +155,7 @@ static int fat_direct_spinand_write_data(char *fpath, struct mtd_dev *mtd,
}
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
return ret;
}
@@ -216,7 +216,7 @@ static int fat_direct_spinand_write_nftl(char *fpath, u32 doffset)
goto out;
}
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
if (!buf) {
pr_err("Failed to malloc buffer.\n");
ret = -1;
@@ -255,7 +255,7 @@ static int fat_direct_spinand_write_nftl(char *fpath, u32 doffset)
out:
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
if (nftl && nftl->nandt)
aicos_free(MEM_CMA, nftl->nandt);
if (nftl)

View File

@@ -58,7 +58,7 @@ int fat_direct_write_spinor(u32 spi_id, char *fpath, u32 doffset)
printf("Programming %s to 0x%x\n", fpath, doffset);
printf("\t");
buf = aicos_malloc_align(0, MAX_WRITE_SIZE, FRAME_LIST_SIZE);
buf = aicupg_malloc_align(MAX_WRITE_SIZE, FRAME_LIST_SIZE);
soffset = 0;
writecnt = 0;
@@ -103,7 +103,7 @@ int fat_direct_write_spinor(u32 spi_id, char *fpath, u32 doffset)
}
if (buf)
aicos_free_align(0, buf);
aicupg_free_align(buf);
printf("\n");
return ret;
}

View File

@@ -451,3 +451,13 @@ void media_data_write_end(struct fwc_info *fwc)
break;
}
}
void *aicupg_malloc_align(u32 size, size_t align)
{
return aicos_malloc_align(MEM_RESERVED, size, align);
}
void aicupg_free_align(void *ptr)
{
aicos_free_align(MEM_RESERVED, ptr);
}

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2023, Artinchip Technology Co., Ltd
* Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Wu Dehuang <dehuang.wu@artinchip.com>
* Authors: Wu Dehuang <dehuang.wu@artinchip.com>
*/
#include <stdio.h>
@@ -487,8 +487,8 @@ static s32 exfat_search_file(struct fat_volume *vol, struct fat_file *file,
/* Bingo */
file->start_clus = first_cluster;
file->size = data_len;
pr_err("Start cluster: 0x%X\n", file->start_clus);
pr_err("bootcfg file size: 0x%X\n", file->size);
pr_debug("Start cluster: 0x%X\n", file->start_clus);
pr_debug("bootcfg file size: 0x%X\n", file->size);
return 0;
}
}

View File

@@ -63,7 +63,7 @@ struct hal_axicfg_table axi_cfg_table[HAL_AXICFG_PORT_MAX] = {
static void aic_board_heap_init(enum boot_device bd)
{
size_t heap_size, heap_start, real_ram_size = 0;
size_t real_ram_size = 0;
#if AIC_PSRAM_SIZE
config_ram_size = AIC_PSRAM_SIZE;
@@ -79,15 +79,7 @@ static void aic_board_heap_init(enum boot_device bd)
if (config_ram_size != real_ram_size)
pr_warn("config ram size(0x%x) is not equal real ram size(0x%x)\n", (u32)config_ram_size, (u32)real_ram_size);
heap_size = ((size_t)&__heap_end) - ((size_t)&__heap_start);
/* Limit bootloader's heap to 2MB */
if (bd != BD_UDISK && bd != BD_SDFAT32 && bd != BD_USB && heap_size > 0x200000)
heap_size = 0x200000;
heap_start = (size_t)&__heap_end - heap_size;
heap_init((void *)heap_start, heap_size);
heap_init();
}
static int board_init(enum boot_device bd)

View File

@@ -313,22 +313,27 @@ config AIC_CIR_DRV_TEST
depends on AIC_CIR_DRV
config AIC_AUDIO_DRV_TEST
bool "Enable audio driver test command"
bool "Enable Audio driver test command"
default n
depends on AIC_AUDIO_DRV
select RT_USING_LEGACY
config AIC_I2S_DRV_TEST
bool "Enable i2s driver test command"
bool "Enable I2S driver test command"
default n
depends on AIC_I2S_DRV
select RT_USING_LEGACY
config AIC_I2C_DRV_TEST
bool "Enable i2c driver test command"
bool "Enable I2C driver test command"
default n
depends on AIC_I2C_DRV
config AIC_CAMERA_DRV_TEST
bool "Enable Camera driver test command"
default n
depends on AIC_USING_CAMERA
config AIC_DVP_TEST
bool "Enable DVP driver test command"
default n
@@ -400,6 +405,11 @@ config AIC_QEP_DRV_TEST
default n
depends on AIC_QEP_DRV
config AIC_DCE_DRV_TEST
bool "Enable Dce driver test command"
default n
depends on AIC_DCE_DRV
config AIC_ADCIM_DM_TEST
bool "Enable ADCIM DM test command"
default n

View File

@@ -88,9 +88,12 @@ if GetDepend('AIC_QSPI_DRV'):
ver = ver.replace('"','')
if GetDepend('DRIVER_DRV_EN'):
src += Glob('drv/qspi/*.c')
src += Glob('drv/spi/*.c')
if GetDepend('DRIVER_HAL_EN'):
src += Glob('hal/qspi/*.c', exclude=['hal/qspi/*_v*.c'])
src += Glob('hal/qspi/*_v%sx.c' % (ver[0]))
if GetDepend('DRIVER_BARE_DRV_EN') and GetDepend('AIC_QSPI_DRV_TEST'):
src += Glob('drv_bare/qspi/*.c')
# XSPI driver
if GetDepend('AIC_XSPI_DRV'):
@@ -378,6 +381,8 @@ if GetDepend('AIC_PWM_DRV'):
if GetDepend('DRIVER_HAL_EN'):
src += Glob('hal/pwm/*.c')
src += Glob('drv/xpwm/xpwm_info_v11.c')
if GetDepend('DRIVER_HAL_EN'):
src += Glob('hal/xpwm/*.c')
if GetDepend('AIC_HRTIMER_DRV_V12'):
@@ -443,6 +448,13 @@ if GetDepend('AIC_CE_DRV'):
if GetDepend('DRIVER_HAL_EN'):
src += Glob('hal/ce/*.c')
# DCE driver
if GetDepend('AIC_DCE_DRV'):
if GetDepend('DRIVER_DRV_EN'):
src += Glob('drv/dce/*.c')
if GetDepend('DRIVER_HAL_EN'):
src += Glob('hal/dce/*.c')
# TOUCH driver
if GetDepend('AIC_USING_TOUCH') and GetDepend('KERNEL_BAREMETAL'):
if GetDepend('DRIVER_BARE_DRV_EN'):

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -15,6 +15,10 @@
#include <hw_symmetric.h>
#include <hw_bignum.h>
#include <hal_ce.h>
#ifdef AIC_DCE_DRV
#include <hal_dce.h>
#include <hw_crc.h>
#endif
#define AES_BLOCK_SIZE 16
#define AES_MAX_KEY_LEN 32
@@ -649,6 +653,66 @@ static const struct hwcrypto_hash_ops hash_ops = {
.finish = drv_hash_finish,
};
#ifdef AIC_DCE_DRV
#define CRC_32_POLY 0x04C11DB7
rt_err_t drv_crc_init(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
res = hal_dce_init();
if (res)
res = -RT_ERROR;
return res;
}
static rt_uint32_t drv_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in,
rt_size_t length)
{
rt_uint32_t crc_result = 0, ret;
if (ctx->crc_cfg.poly != CRC_32_POLY) {
pr_err("Artinchip hardware crc only support CRC_32_POLY.\n");
return -RT_ERROR;
}
if (ctx->crc_cfg.xorout)
hal_dce_crc32_xor_val(ctx->crc_cfg.xorout);
if (ctx->crc_cfg.flags)
hal_dce_crc32_cfg((ctx->crc_cfg.flags & CRC_FLAG_REFIN), 0,
(ctx->crc_cfg.flags & CRC_FLAG_REFIN),
(ctx->crc_cfg.flags & CRC_FLAG_REFOUT));
hal_dce_crc32_start(ctx->crc_cfg.last_val, (u8 *)in, length);
ret = hal_dce_crc32_wait();
if (!ret) {
crc_result = hal_dce_crc32_result();
} else {
pr_err("\t%s error: time out\n", __func__);
return -RT_ERROR;
}
ctx->crc_cfg.last_val = crc_result;
return crc_result;
}
void drv_crc_uninit(struct rt_hwcrypto_ctx *ctx)
{
if (!ctx)
return;
if (ctx->contex) {
aicos_free_align(0, ctx->contex);
ctx->contex = NULL;
}
hal_dce_deinit();
}
static const struct hwcrypto_crc_ops crc_ops = {
.update = drv_crc_update,
};
#endif
static rt_err_t aic_hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
@@ -677,6 +741,12 @@ static rt_err_t aic_hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
/* Setup HASH operation */
((struct hwcrypto_hash *)ctx)->ops = &hash_ops;
break;
#ifdef AIC_DCE_DRV
case HWCRYPTO_TYPE_CRC:
drv_crc_init(ctx);
((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
break;
#endif
default:
res = -RT_ERROR;
break;
@@ -703,6 +773,11 @@ static void aic_hwcrypto_destroy(struct rt_hwcrypto_ctx *ctx)
case HWCRYPTO_TYPE_SHA2:
drv_sha_uninit(ctx);
break;
#ifdef AIC_DCE_DRV
case HWCRYPTO_TYPE_CRC:
drv_crc_uninit(ctx);
break;
#endif
default:
break;
}
@@ -743,7 +818,6 @@ static void aic_hwcrypto_reset(struct rt_hwcrypto_ctx *ctx)
break;
case HWCRYPTO_TYPE_RC4:
case HWCRYPTO_TYPE_RNG:
case HWCRYPTO_TYPE_CRC:
break;
case HWCRYPTO_TYPE_BIGNUM:
drv_rsa_init(ctx);
@@ -754,6 +828,11 @@ static void aic_hwcrypto_reset(struct rt_hwcrypto_ctx *ctx)
drv_sha_init(ctx);
drv_sha_start(ctx);
break;
#ifdef AIC_DCE_DRV
case HWCRYPTO_TYPE_CRC:
drv_crc_init(ctx);
break;
#endif
default:
break;
}

View File

@@ -3,7 +3,7 @@
#-----------------------------
menu "CIR protocol select"
depends on AIC_USING_CIR
depends on (AIC_USING_CIR || AIC_USING_R_CIR)
config AIC_CIR_NEC
bool "NEC protocol"

View File

@@ -180,6 +180,15 @@ int rt_hw_aic_cir_init(void)
aic_cir_dev.dev.type = RT_Device_Class_Char;
#endif
#ifdef AIC_USING_R_CIR
aic_cir_dev.aic_cir_ctrl.cir_base = R_CIR_BASE;
aic_cir_dev.aic_cir_ctrl.irq_num = R_CIR_IRQn;
#else
aic_cir_dev.aic_cir_ctrl.cir_base = CIR_BASE;
aic_cir_dev.aic_cir_ctrl.irq_num = CIR_IRQn;
#endif
aic_cir_dev.aic_cir_ctrl.clk_idx = CLK_CIR;
rt_mutex_init(&aic_cir_dev.lock, "cir_mutex", RT_IPC_FLAG_PRIO);
rt_device_register(&aic_cir_dev.dev, "cir", 0);
LOG_I("ArtInChip CIR device register success\n");

View File

@@ -0,0 +1,3 @@
#-----------------------------
# devices local parameter
#-----------------------------

View File

@@ -0,0 +1,8 @@
/*
* Copyright (c) 2024, ArtInChip Technology CO.,LTD. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: Chen Junlong <junlong.chen@artinchip.com>
*/
/* do nothing, dce drv is implemented in ce drv */

View File

@@ -225,3 +225,26 @@ endif
config AIC_PANEL_SPI_EMULATION
bool
default n
config AIC_SCREEN_CROP
bool "Enable screen crop"
default n
help
Some LCD screen need to be cropped, the effective area displayed is less
than the timing signal.
If unsure select "N".
if AIC_SCREEN_CROP
config AIC_SCREEN_CROP_POS_X
int "screen crop x position of pixels"
default 0
config AIC_SCREEN_CROP_POS_Y
int "screen crop y position of pixels"
default 0
config AIC_SCREEN_CROP_WIDTH
int "screen crop width"
default 0
config AIC_SCREEN_CROP_HEIGHT
int "screen crop height"
default 0
endif

View File

@@ -21,17 +21,42 @@
/**
* lvds channel output order
*
* default D3 CK D2 D1 D0
* 4 3 2 1 0
* link 0 default D3 CK D2 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
*
* link 1 default D3 CK D2 D1 D0
* PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
*
*
* link 0 example:
* D2 CK D3 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
*
* AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D2, LVDS_CK, LVDS_D3, LVDS_D1, LVDS_D0)
* link1 example is the same as link0
*/
#define AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
#define AIC_LVDS_LINK1_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
/**
* lvds channel polarities
*
* link 0 default PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
* N/P N/P N/P N/P N/P
*
* link 1 default PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
* N/P N/P N/P N/P N/P
*
*
* link 0 example:
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
* N/P P/N N/P P/N N/P
*
* AIC_LVDS_LINK0_POL 0b01010
* link1 example is the same as link0
*/
#define AIC_LVDS_LINK0_POL 0x0
#define AIC_LVDS_LINK1_POL 0x0
#define AIC_LVDS_LINK0_POL 0b00000
#define AIC_LVDS_LINK1_POL 0b00000
/**
* lvds channel phy config
@@ -43,13 +68,41 @@
* MIPI-DSI options
*/
/* data line assignments */
/**
* data lane assignments
*
* default D3 D2 D1 D0
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
*
* example D0 D1 D2 D3
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
*
* LANE_ASSIGNMENTS 0x0123
*/
#define LANE_ASSIGNMENTS 0x3210
/* data line polarities */
/**
* data lane polarities
*
* default PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
* N/P N/P N/P N/P
*
* example PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
* P/N N/P P/N N/P
*
* LANE_POLARITIES 0b1010
*/
#define LANE_POLARITIES 0b0000
/* data clk inverse */
/**
* data clk inverse
*
* default PD24/PD25
* N/P
*
* CLK_INVERSE 1 PD24/PD25
* P/N
*/
#define CLK_INVERSE 0
/* virtual channel id */

View File

@@ -17,9 +17,11 @@
#define DE_TIMEOUT_MS 100
static unsigned int vsync_flag = 0;
static struct aic_de_comp *g_aic_de_comp;
static int aic_de_set_gamma_config(struct aicfb_gamma_config *gamma);
static int aic_de_set_ccm_config(struct aicfb_ccm_config *ccm);
static struct aic_de_comp *aic_de_request_drvdata(void)
{
return g_aic_de_comp;
@@ -38,10 +40,8 @@ static irqreturn_t aic_de_handler(int irq, void *ctx)
status = de_timing_interrupt_status(comp->regs);
de_timing_interrupt_clean_status(comp->regs, status);
if ((status & TIMING_INIT_V_BLANK_FLAG) && vsync_flag) {
vsync_flag = 0;
if (status & TIMING_INIT_V_BLANK_FLAG)
aicos_wqueue_wakeup(comp->vsync_queue);
}
if (comp->scaler_active & SCALER0_CTRL_ACTIVE) {
comp->scaler_active = comp->scaler_active & 0xF;
@@ -237,6 +237,9 @@ static int aic_de_timing_enable(void)
de_timing_enable_interrupt(comp->regs, true, TIMING_INIT_UNDERFLOW_FLAG);
#endif
aic_de_set_gamma_config(&comp->gamma);
aic_de_set_ccm_config(&comp->ccm);
de_timing_enable(comp->regs, 1);
aic_de_release_drvdata();
@@ -257,7 +260,6 @@ static int aic_de_wait_for_vsync(void)
struct aic_de_comp *comp = aic_de_request_drvdata();
int ret = 0;
vsync_flag = 1;
ret = aicos_wqueue_wait(comp->vsync_queue, DE_TIMEOUT_MS);
if (ret < 0) {
hal_log_err("DE wait vsync irq failed, ret: %d\n", ret);

View File

@@ -208,6 +208,11 @@ int config_ui_layer_rect(struct aic_de_comp *comp,
de_ui_layer_enable(comp->regs, 1);
}
#ifdef AIC_SCREEN_CROP
x_offset += AIC_SCREEN_CROP_POS_X;
y_offset += AIC_SCREEN_CROP_POS_Y;
#endif
de_ui_layer_set_rect(comp->regs, in_w, in_h, x_offset, y_offset,
stride0, addr0, layer_data->rect_id);
de_ui_layer_rect_enable(comp->regs, layer_data->rect_id, 1);

View File

@@ -746,6 +746,18 @@ static int de_vi_layer_config_format(struct aic_de_comp *comp,
return -EINVAL;
}
static void de_vi_layer_config_crop_pos(struct aic_de_comp *comp,
struct aicfb_layer_data *layer_data)
{
#ifdef AIC_SCREEN_CROP
u32 x_offset = layer_data->pos.x + AIC_SCREEN_CROP_POS_X;
u32 y_offset = layer_data->pos.y + AIC_SCREEN_CROP_POS_Y;
reg_write(comp->regs + VIDEO_LAYER_OFFSET,
VIDEO_LAYER_OFFSET_SET(x_offset, y_offset));
#endif
}
int config_video_layer(struct aic_de_comp *comp,
struct aicfb_layer_data *layer_data)
{
@@ -766,6 +778,7 @@ int config_video_layer(struct aic_de_comp *comp,
}
de_vi_layer_config_format(comp, format_info, layer_data);
de_vi_layer_config_crop_pos(comp, layer_data);
return 0;
}

View File

@@ -688,15 +688,20 @@ static void aicfb_fb_info_setup(struct aicfb_info *fbi)
fbi->fb_rotate = 0;
#endif
if (fbi->fb_rotate == 90 || fbi->fb_rotate == 270)
{
active_w = fbi->panel->timings->vactive;
active_h = fbi->panel->timings->hactive;
}
else
{
#ifdef AIC_SCREEN_CROP
active_w = AIC_SCREEN_CROP_WIDTH;
active_h = AIC_SCREEN_CROP_HEIGHT;
#else
active_w = fbi->panel->timings->hactive;
active_h = fbi->panel->timings->vactive;
#endif
if (fbi->fb_rotate == 90 || fbi->fb_rotate == 270)
{
u32 tmp = active_w;
active_w = active_h;
active_h = tmp;
}
stride = ALIGN_8B(active_w * bpp / 8);
@@ -724,8 +729,8 @@ static void fb_color_block(struct aicfb_info *fbi)
};
unsigned char *pos = (unsigned char *)fbi->fb_start;
width = fbi->panel->timings->hactive;
height = fbi->panel->timings->vactive;
width = fbi->width;
height = fbi->height;
switch (fbi->bits_per_pixel) {
#if defined(AICFB_ARGB8888) || defined(AICFB_ABGR8888) || defined(AICFB_XRGB8888)
@@ -818,7 +823,6 @@ static void aicfb_update_alpha(struct aicfb_info *fbi)
static void aicfb_update_layer(struct aicfb_info *fbi)
{
struct platform_driver *de = fbi->de;
struct aic_panel *panel = fbi->panel;
struct aicfb_layer_data layer = {0};
layer.layer_id = AICFB_LAYER_TYPE_UI;
@@ -830,11 +834,10 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
switch (fbi->fb_rotate)
{
case 0:
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->width;
layer.buf.size.height = fbi->height;
layer.buf.stride[0] = fbi->stride;
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start;
layer.buf.format = AICFB_FORMAT;
break;
#ifdef AIC_FB_ROTATE_EN
case 90:
@@ -843,16 +846,15 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
unsigned int stride = ALIGN_8B(fbi->height * fbi->bits_per_pixel / 8);
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->height;
layer.buf.size.height = fbi->width;
layer.buf.stride[0] = stride;
break;
}
case 180:
pr_info("rotate 180\n");
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
layer.buf.size.width = panel->timings->hactive;
layer.buf.size.height = panel->timings->vactive;
layer.buf.size.width = fbi->width;
layer.buf.size.height = fbi->height;
layer.buf.stride[0] = fbi->stride;
break;
#endif

View File

@@ -2,6 +2,25 @@
# i2c devices local parameter
#-----------------------------
# soft_i2c parameter
menu "SOFT_I2C Parameter"
depends on AIC_USING_SOFT_I2C
config AIC_SOFT_I2C_SCL_PIN
string "SOFT_I2C SCL PIN"
default "PD.6"
config AIC_SOFT_I2C_SDA_PIN
string "SOFT_I2C SDA PIN"
default "PD.7"
config AIC_DEV_SOFT_I2C_DELAY_TIME
int "Setting SOFT_I2C GPIO Level Change Delay Time(us)"
default 5
endmenu
# i2c0 parameter
menu "I2C0 Parameter"

View File

@@ -117,17 +117,24 @@ struct aic_i2c_bus {
struct rt_completion cmd_complete;
};
static struct aic_i2c_bus g_aic_i2c_dev[AIC_I2C_CH_NUM];
static struct aic_i2c_bus g_aic_i2c_dev[I2C_MAX_CHAN];
irqreturn_t aic_i2c_slave_irqhandler(int irq, void * data)
{
int index = irq - I2C0_IRQn;
int i, index = 0;
uint32_t intr_stat;
uint8_t val;
uint8_t fifo_num;
struct slave_param parm;
aic_i2c_ctrl *i2c_dev;
for (i = 0; i < I2C_MAX_CHAN; i++) {
if (irq == g_aic_i2c_dev[i].aic_bus.irq_index) {
index = i;
break;
}
}
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
intr_stat = hal_i2c_get_raw_interrupt_state(i2c_dev);
fifo_num = hal_i2c_get_receive_fifo_num(i2c_dev);
@@ -280,10 +287,17 @@ static void aic_i2c_handle_write(struct aic_i2c_ctrl *i2c_dev)
irqreturn_t aic_i2c_irqhandler(int irq, void * data)
{
int index = irq - I2C0_IRQn;
int i, index = 0;
uint32_t status = 0;
aic_i2c_ctrl *i2c_dev;
for (i = 0; i < I2C_MAX_CHAN; i++) {
if (irq == g_aic_i2c_dev[i].aic_bus.irq_index) {
index = i;
break;
}
}
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
status = hal_i2c_get_raw_interrupt_state(i2c_dev);
/* clear all interrupt flags */
@@ -386,7 +400,7 @@ static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
}
hal_i2c_module_disable(i2c_dev);
return (ret < 0) ? ret : num;
return (ret < 0) ? 0 : num;
}
#else
static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,

View File

@@ -0,0 +1,102 @@
/*
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: hjh <jiehua.huang@artinchip.com>
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <aic_core.h>
#include <stdint.h>
#include <stdbool.h>
#include <drivers/i2c-bit-ops.h>
#include "aic_hal_clk.h"
#include "aic_common.h"
#include "aic_log.h"
#define AIC_SOFT_I2C_TIMEOUT 1000
struct aic_soft_i2c_pin {
u32 sda_pin;
u32 scl_pin;
};
struct aic_soft_i2c_bus {
struct rt_i2c_bus_device bus;
struct aic_soft_i2c_pin aic_i2c_pin;
};
static struct aic_soft_i2c_bus g_aic_soft_i2c;
static void aic_soft_i2c_set_sda(void *data, rt_int32_t state)
{
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.sda_pin, PIN_MODE_OUTPUT);
rt_pin_write(g_aic_soft_i2c.aic_i2c_pin.sda_pin, state);
}
static void aic_soft_i2c_set_scl(void *data, rt_int32_t state)
{
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.scl_pin, PIN_MODE_OUTPUT);
rt_pin_write(g_aic_soft_i2c.aic_i2c_pin.scl_pin, state);
}
static rt_int32_t aic_soft_i2c_get_sda(void *data)
{
rt_int32_t ret;
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.sda_pin, PIN_MODE_INPUT_PULLUP);
ret = rt_pin_read(g_aic_soft_i2c.aic_i2c_pin.sda_pin);
return ret;
}
static rt_int32_t aic_soft_i2c_get_scl(void *data)
{
rt_int32_t ret;
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.scl_pin, PIN_MODE_INPUT_PULLUP);
ret = rt_pin_read(g_aic_soft_i2c.aic_i2c_pin.scl_pin);
return ret;
}
static void aic_soft_i2c_udelay(rt_uint32_t us)
{
aic_udelay(us);
}
struct rt_i2c_bit_ops aic_soft_i2c_ops = {
.data = NULL,
.set_sda = aic_soft_i2c_set_sda,
.set_scl = aic_soft_i2c_set_scl,
.get_sda = aic_soft_i2c_get_sda,
.get_scl = aic_soft_i2c_get_scl,
.udelay = aic_soft_i2c_udelay,
#ifdef AIC_USING_SOFT_I2C
.delay_us = AIC_DEV_SOFT_I2C_DELAY_TIME,
#endif
.timeout = AIC_SOFT_I2C_TIMEOUT,
};
static int aic_soft_i2c_register()
{
int ret = RT_EOK;
#ifdef AIC_USING_SOFT_I2C
g_aic_soft_i2c.aic_i2c_pin.sda_pin = rt_pin_get(AIC_SOFT_I2C_SDA_PIN);
g_aic_soft_i2c.aic_i2c_pin.scl_pin = rt_pin_get(AIC_SOFT_I2C_SCL_PIN);
g_aic_soft_i2c.bus.priv = &aic_soft_i2c_ops;
ret = rt_i2c_bit_add_bus(&g_aic_soft_i2c.bus, "soft_i2c");
if (ret) {
hal_log_err("register soft i2c fail\r\n");
return ret;
}
#endif
return ret;
}
INIT_DEVICE_EXPORT(aic_soft_i2c_register);

View File

@@ -1,9 +1,9 @@
/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Li Siyao <siyao.li@artinchip.com>
* Authors: Siyao Li <siyao.li@artinchip.com>
*/
#include <stdbool.h>
@@ -229,9 +229,16 @@ static rt_uint8_t drv_psadc_resolution(struct rt_adc_device *dev)
return 12;
}
static rt_err_t drv_psadc_convert(struct rt_adc_device *dev, rt_uint32_t ch,
rt_uint32_t *value)
{
return RT_EOK;
}
static const struct rt_adc_ops aic_adc_ops =
{
.enabled = drv_psadc_enabled,
.convert = drv_psadc_convert,
.get_resolution = drv_psadc_resolution,
.get_adc_values_poll = drv_psadc_get_adc_values_poll,
.get_adc_values = drv_psadc_get_adc_values,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -57,7 +57,7 @@ static struct aic_qspi qspi_controller[] = {
#endif
},
#endif
#if defined(AIC_USING_QSPI1)
#if defined(AIC_USING_QSPI1) && !defined(AIC_QSPI1_BUS_SPI)
{
.name = "qspi1",
.idx = 1,
@@ -75,7 +75,7 @@ static struct aic_qspi qspi_controller[] = {
#endif
},
#endif
#if defined(AIC_USING_QSPI2)
#if defined(AIC_USING_QSPI2) && !defined(AIC_QSPI2_BUS_SPI)
{
.name = "qspi2",
.idx = 2,
@@ -93,7 +93,7 @@ static struct aic_qspi qspi_controller[] = {
#endif
},
#endif
#if defined(AIC_USING_QSPI3)
#if defined(AIC_USING_QSPI3) && !defined(AIC_QSPI3_BUS_SPI)
{
.name = "qspi3",
.idx = 3,
@@ -111,7 +111,7 @@ static struct aic_qspi qspi_controller[] = {
#endif
},
#endif
#if defined(AIC_USING_QSPI4)
#if defined(AIC_USING_QSPI4) && !defined(AIC_QSPI4_BUS_SPI)
{
.name = "qspi4",
.idx = 4,

View File

@@ -0,0 +1,455 @@
/*
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Jiji Chen <jiji.chen@artinchip.com>
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
#include <aic_core.h>
#include <aic_drv.h>
#include <aic_hal.h>
#include <hal_qspi.h>
#include <hal_dma.h>
#include <aic_dma_id.h>
#include <aic_clk_id.h>
#define ASYNC_DATA_SIZE 64
struct aic_qspi {
struct rt_spi_bus dev;
char *name;
uint32_t idx;
uint32_t clk_id;
uint32_t clk_in_hz;
uint32_t dma_port_id;
uint32_t irq_num;
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
uint32_t cs_num;
#endif
qspi_master_handle handle;
struct rt_qspi_configuration configuration;
rt_sem_t xfer_sem;
bool inited;
uint32_t rxd_dlymode;
uint32_t txd_dlymode;
uint32_t txc_dlymode;
bool nonblock;
};
static struct aic_qspi spi_controller[] = {
#if defined(AIC_USING_QSPI1) && defined(AIC_QSPI1_BUS_SPI)
{
.name = "spi1",
.idx = 1,
.clk_id = CLK_QSPI1,
.clk_in_hz = AIC_DEV_QSPI1_MAX_SRC_FREQ_HZ,
.dma_port_id = DMA_ID_SPI1,
.irq_num = QSPI1_IRQn,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI1_CS_NUM,
#endif
.rxd_dlymode = AIC_DEV_QSPI1_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dlymode = AIC_DEV_QSPI1_TXD_DELAY_MODE,
.txc_dlymode = AIC_DEV_QSPI1_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI2) && defined(AIC_QSPI2_BUS_SPI)
{
.name = "spi2",
.idx = 2,
.clk_id = CLK_QSPI2,
.clk_in_hz = AIC_DEV_QSPI2_MAX_SRC_FREQ_HZ,
.dma_port_id = DMA_ID_SPI2,
.irq_num = QSPI2_IRQn,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI2_CS_NUM,
#endif
.rxd_dlymode = AIC_DEV_QSPI2_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dlymode = AIC_DEV_QSPI2_TXD_DELAY_MODE,
.txc_dlymode = AIC_DEV_QSPI2_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI3) && defined(AIC_QSPI3_BUS_SPI)
{
.name = "spi3",
.idx = 3,
.clk_id = CLK_QSPI3,
.clk_in_hz = AIC_DEV_QSPI3_MAX_SRC_FREQ_HZ,
.dma_port_id = DMA_ID_SPI3,
.irq_num = QSPI3_IRQn,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI3_CS_NUM,
#endif
.rxd_dlymode = AIC_DEV_QSPI3_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dlymode = AIC_DEV_QSPI3_TXD_DELAY_MODE,
.txc_dlymode = AIC_DEV_QSPI3_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI4) && defined(AIC_QSPI4_BUS_SPI)
{
.name = "spi4",
.idx = 4,
.clk_id = CLK_QSPI4,
.clk_in_hz = AIC_DEV_QSPI4_MAX_SRC_FREQ_HZ,
.dma_port_id = DMA_ID_SPI4,
.irq_num = QSPI4_IRQn,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI4_CS_NUM,
#endif
.rxd_dlymode = AIC_DEV_QSPI4_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dlymode = AIC_DEV_QSPI4_TXD_DELAY_MODE,
.txc_dlymode = AIC_DEV_QSPI4_TX_CLK_DELAY_MODE,
#endif
},
#endif
};
static const u32 bit_mode_table[] = {
#ifdef AIC_QSPI1_BIT_MODE
1,
#endif
#ifdef AIC_QSPI2_BIT_MODE
2,
#endif
#ifdef AIC_QSPI3_BIT_MODE
3,
#endif
};
static bool spi_support_bit_mode(struct aic_qspi *qspi)
{
u32 i;
for (i = 0; i < ARRAY_SIZE(bit_mode_table); i++) {
if (bit_mode_table[i] == qspi->idx)
return true;
}
return false;
}
#ifdef AIC_QSPI_DRV_DEBUG
void dump_cmd(uint8_t *data, uint32_t len)
{
uint32_t i;
printf("CMD: (%lu) ", (unsigned long)len);
for (i = 0; i < len; i++)
printf("%02X ", data[i]);
printf("\n");
}
#endif
static rt_uint32_t drv_spi_send(struct aic_qspi *qspi,
struct rt_spi_message *message,
const uint8_t *tx, uint32_t size)
{
struct qspi_transfer t;
u32 ret = 0;
t.rx_data = NULL;
t.tx_data = (uint8_t *)tx;
t.data_len = size;
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
return ret;
}
static rt_uint32_t drv_spi_receive(struct aic_qspi *qspi,
struct rt_spi_message *message,
const uint8_t *tx, uint32_t size)
{
struct qspi_transfer t;
u32 ret = 0;
t.tx_data = NULL;
t.rx_data = (uint8_t *)tx;
t.data_len = size;
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
return ret;
}
static rt_uint32_t drv_spi_transfer(struct aic_qspi *qspi,
struct rt_spi_message *message)
{
u32 ret = 0;
struct qspi_transfer t;
t.tx_data = (u8 *)message->send_buf;
t.rx_data = message->recv_buf;
t.data_len = message->length;
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
return ret;
}
static void spi_set_cs_before(struct rt_spi_device *device,
struct rt_spi_message *message)
{
struct rt_qspi_configuration *cfg;
struct aic_qspi *qspi;
u32 cs_num = 0;
qspi = (struct aic_qspi *)device->bus;
cfg = &qspi->configuration;
if (message->cs_take && !(cfg->parent.mode & RT_SPI_NO_CS)) {
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
cs_num = qspi->cs_num;
#endif
hal_qspi_master_set_cs(&qspi->handle, cs_num, true);
}
}
static void spi_set_cs_after(struct rt_spi_device *device,
struct rt_spi_message *message)
{
struct rt_qspi_configuration *cfg;
struct aic_qspi *qspi;
u32 cs_num = 0;
qspi = (struct aic_qspi *)device->bus;
cfg = &qspi->configuration;
if (message->cs_release && !(cfg->parent.mode & RT_SPI_NO_CS)) {
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
cs_num = qspi->cs_num;
#endif
if (!qspi->nonblock)
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
}
}
static rt_uint32_t spi_xfer(struct rt_spi_device *device,
struct rt_spi_message *message)
{
struct aic_qspi *qspi;
rt_uint32_t ret = 0;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
qspi = (struct aic_qspi *)device->bus;
spi_set_cs_before(device, message);
if (message->recv_buf && message->send_buf)
ret = drv_spi_transfer(qspi, message);
else if (message->recv_buf)
ret = drv_spi_receive(qspi, message, message->recv_buf, message->length);
else if (message->send_buf)
ret = drv_spi_send(qspi, message, message->send_buf, message->length);
spi_set_cs_after(device, message);
if (ret)
return ret;
return message->length;
}
static void qspi_master_async_callback(qspi_master_handle *h, void *priv)
{
struct aic_qspi *qspi = priv;
u32 cs_num = 0;
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
cs_num = qspi->cs_num;
#endif
rt_sem_release(qspi->xfer_sem);
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
}
static irqreturn_t qspi_irq_handler(int irq_num, void *arg)
{
qspi_master_handle *h = arg;
rt_interrupt_enter();
hal_qspi_master_irq_handler(h);
rt_interrupt_leave();
return IRQ_HANDLED;
}
static rt_err_t spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configuration)
{
struct qspi_master_config cfg;
struct aic_qspi *qspi;
rt_uint32_t bus_hz;
rt_err_t ret = RT_EOK;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configuration != RT_NULL);
qspi = (struct aic_qspi *)device->bus;
if (spi_support_bit_mode(qspi))
qspi->handle.bit_mode = true;
else
qspi->handle.bit_mode = false;
if ((rt_memcmp(&qspi->configuration, configuration,
sizeof(struct rt_spi_configuration)) != 0) ||
(qspi->handle.bit_mode == true)) {
rt_memcpy(&qspi->configuration, configuration,
sizeof(struct rt_spi_configuration));
rt_memset(&cfg, 0, sizeof(cfg));
cfg.idx = qspi->idx;
cfg.clk_id = qspi->clk_id;
bus_hz = configuration->max_hz;
if (bus_hz < HAL_QSPI_MIN_FREQ_HZ)
bus_hz = HAL_QSPI_MIN_FREQ_HZ;
if (bus_hz > HAL_QSPI_MAX_FREQ_HZ)
bus_hz = HAL_QSPI_MAX_FREQ_HZ;
cfg.clk_in_hz = qspi->clk_in_hz;
if (cfg.clk_in_hz > HAL_QSPI_MAX_FREQ_HZ)
cfg.clk_in_hz = HAL_QSPI_MAX_FREQ_HZ;
if (qspi->clk_in_hz % bus_hz)
cfg.clk_in_hz = bus_hz;
if (cfg.clk_in_hz < HAL_QSPI_INPUT_MIN_FREQ_HZ)
cfg.clk_in_hz = HAL_QSPI_INPUT_MIN_FREQ_HZ;
if (configuration->mode & RT_SPI_MSB)
cfg.lsb_en = false;
else
cfg.lsb_en = true;
if (configuration->mode & RT_SPI_CPHA)
cfg.cpha = HAL_QSPI_CPHA_SECOND_EDGE;
else
cfg.cpha = HAL_QSPI_CPHA_FIRST_EDGE;
if (configuration->mode & RT_SPI_CPOL)
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_LOW;
else
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_HIGH;
if (configuration->mode & RT_SPI_CS_HIGH)
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_HIGH;
else
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_LOW;
cfg.rx_dlymode = qspi->rxd_dlymode;
cfg.tx_dlymode = aic_convert_tx_dlymode(qspi->txc_dlymode, qspi->txd_dlymode);
ret = hal_qspi_master_init(&qspi->handle, &cfg);
if (ret) {
pr_err("spi init failed.\n");
return ret;
}
if (!qspi->inited) {
#ifdef AIC_DMA_DRV
struct qspi_master_dma_config dmacfg;
rt_memset(&dmacfg, 0, sizeof(dmacfg));
dmacfg.port_id = qspi->dma_port_id;
ret = hal_qspi_master_dma_config(&qspi->handle, &dmacfg);
if (ret) {
pr_err("qspi dma config failed.\n");
return ret;
}
#endif
ret = hal_qspi_master_register_cb(&qspi->handle,
qspi_master_async_callback, qspi);
if (ret) {
pr_err("qspi register async callback failed.\n");
return ret;
}
aicos_request_irq(qspi->irq_num, qspi_irq_handler, 0, NULL,
(void *)&qspi->handle);
aicos_irq_enable(qspi->irq_num);
}
bus_hz = configuration->max_hz;
if (bus_hz > HAL_QSPI_MAX_FREQ_HZ)
bus_hz = HAL_QSPI_MAX_FREQ_HZ;
hal_qspi_master_set_bus_freq(&qspi->handle, bus_hz);
if (ret) {
pr_err("qspi set bus frequency failed.\n");
return ret;
}
}
qspi->inited = true;
return ret;
}
static rt_err_t spi_nonblock_set(struct rt_spi_device *device,
rt_uint32_t nonblock)
{
struct aic_qspi *qspi;
qspi = (struct aic_qspi *)device->bus;
if (nonblock == 1)
qspi->nonblock = true;
else
qspi->nonblock = false;
return RT_EOK;
}
static rt_uint32_t spi_get_transfer_status(struct rt_spi_device *device)
{
struct aic_qspi *qspi;
qspi = (struct aic_qspi *)device->bus;
return hal_qspi_master_get_status(&qspi->handle);
}
rt_err_t aic_spi_bus_attach_device(const char *bus_name,
const char *device_name)
{
struct rt_spi_device *spi_device = RT_NULL;
rt_err_t result = RT_EOK;
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
spi_device =
(struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
result = rt_spi_bus_attach_device(spi_device, device_name,
bus_name, RT_NULL);
if (result != RT_EOK && spi_device != NULL)
rt_free(spi_device);
return result;
}
static const struct rt_spi_ops aic_spi_ops = {
.configure = spi_configure,
.xfer = spi_xfer,
.nonblock = spi_nonblock_set,
.gstatus = spi_get_transfer_status,
};
static int rt_hw_spi_bus_init(void)
{
char sem_name[RT_NAME_MAX];
rt_err_t ret = RT_EOK;
int i;
for (i = 0; i < ARRAY_SIZE(spi_controller); i++) {
ret = rt_spi_bus_register(&spi_controller[i].dev,
spi_controller[i].name, &aic_spi_ops);
if (ret != RT_EOK)
break;
rt_sprintf(sem_name, "%s_s", spi_controller[i].name);
spi_controller[i].xfer_sem =
rt_sem_create(sem_name, 0, RT_IPC_FLAG_PRIO);
if (!spi_controller[i].xfer_sem) {
ret = RT_ENOMEM;
break;
}
}
return ret;
}
INIT_BOARD_EXPORT(rt_hw_spi_bus_init);

View File

@@ -94,6 +94,10 @@ menu "UART0 Parameter"
default 6 if AIC_DEV_UART0_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART0_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART0_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART0_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART0_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART0_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -258,6 +262,10 @@ menu "UART1 Parameter"
default 6 if AIC_DEV_UART1_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART1_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART1_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART1_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART1_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART1_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -422,6 +430,9 @@ menu "UART2 Parameter"
default 6 if AIC_DEV_UART2_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART2_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART2_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART2_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART2_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART2_RTS_ENABLE
bool
@@ -588,6 +599,10 @@ menu "UART3 Parameter"
default 6 if AIC_DEV_UART3_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART3_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART3_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART3_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART3_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART3_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -752,6 +767,10 @@ menu "UART4 Parameter"
default 6 if AIC_DEV_UART4_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART4_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART4_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART4_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART4_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART4_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -917,6 +936,10 @@ menu "UART5 Parameter"
default 6 if AIC_DEV_UART5_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART5_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART5_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART5_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART5_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART5_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -1081,6 +1104,10 @@ menu "UART6 Parameter"
default 6 if AIC_DEV_UART6_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART6_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART6_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART6_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART6_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART6_RTS_ENABLE
bool
prompt "Enable RTS"
@@ -1245,6 +1272,10 @@ menu "UART7 Parameter"
default 6 if AIC_DEV_UART7_MODE_RS232_SW_HW_FLOW_CTRL
default 7 if AIC_DEV_UART7_MODE_RS485_SIMULATION
config AIC_SERIAL_USING_FLOWCTRL
bool
default y if AIC_DEV_UART7_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART7_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART7_MODE_RS232_SW_HW_FLOW_CTRL
menuconfig AIC_UART7_RTS_ENABLE
bool
prompt "Enable RTS"

View File

@@ -1,3 +1,11 @@
/*
* Copyright (c) 2023-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Wu Dehuang <dehuang.wu@artinchip.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -383,7 +391,8 @@ static int console_run_cmd_internal(struct tiny_console *cons,
for (c = root; c; c = c->next) {
int rc = CONSOLE_OK;
if (strncasecmp(c->cmdname, args[starg_arg], strlen(args[starg_arg])))
if (strncasecmp(c->cmdname, args[starg_arg], strlen(c->cmdname)) ||
strlen(c->cmdname) != strlen(args[starg_arg]))
continue;
/* name is matched */

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: jiji.chen <jiji.chen@artinchip.com>
*/
#include <rtconfig.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sfud.h>
#include <aic_common.h>
#include <aic_core.h>
#include <aic_soc.h>
#include <aic_log.h>
#include <aic_hal.h>
#include <hal_qspi.h>
#include <spinor_port.h>
#include <hal_dma.h>
#include <aic_dma_id.h>
#include <aic_clk_id.h>
static struct aic_qspi_bus qspi_bus_arr[] = {
#if defined(AIC_USING_QSPI0) && defined(AIC_QSPI0_DEVICE_SPINOR)
{
.name = "qspi0",
.idx = 0,
.clk_id = CLK_QSPI0,
.clk_in_hz = AIC_DEV_QSPI0_MAX_SRC_FREQ_HZ,
.bus_hz = AIC_QSPI0_DEVICE_SPINOR_FREQ,
.dma_port_id = DMA_ID_SPI0,
.irq_num = QSPI0_IRQn,
.dl_width = AIC_QSPI0_BUS_WIDTH,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI0_CS_NUM,
#endif
.rxd_dylmode = AIC_DEV_QSPI0_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dylmode = AIC_DEV_QSPI0_TXD_DELAY_MODE,
.txc_dylmode = AIC_DEV_QSPI0_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI1) && defined(AIC_QSPI1_DEVICE_SPINOR)
{
.name = "qspi1",
.idx = 1,
.clk_id = CLK_QSPI1,
.clk_in_hz = AIC_DEV_QSPI1_MAX_SRC_FREQ_HZ,
.bus_hz = AIC_QSPI1_DEVICE_SPINOR_FREQ,
.dma_port_id = DMA_ID_SPI1,
.irq_num = QSPI1_IRQn,
.dl_width = AIC_QSPI1_BUS_WIDTH,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI1_CS_NUM,
#endif
.rxd_dylmode = AIC_DEV_QSPI1_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dylmode = AIC_DEV_QSPI1_TXD_DELAY_MODE,
.txc_dylmode = AIC_DEV_QSPI1_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI2) && defined(AIC_QSPI2_DEVICE_SPINOR)
{
.name = "qspi2",
.idx = 2,
.clk_id = CLK_QSPI2,
.clk_in_hz = AIC_DEV_QSPI2_MAX_SRC_FREQ_HZ,
.bus_hz = AIC_QSPI2_DEVICE_SPINOR_FREQ,
.dma_port_id = DMA_ID_SPI2,
.irq_num = QSPI2_IRQn,
.dl_width = AIC_QSPI2_BUS_WIDTH,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI2_CS_NUM,
#endif
.rxd_dylmode = AIC_DEV_QSPI2_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dylmode = AIC_DEV_QSPI2_TXD_DELAY_MODE,
.txc_dylmode = AIC_DEV_QSPI2_TX_CLK_DELAY_MODE,
#endif
},
#endif
#if defined(AIC_USING_QSPI3)
{
.name = "qspi3",
.idx = 3,
.clk_id = CLK_QSPI3,
.clk_in_hz = AIC_DEV_QSPI3_MAX_SRC_FREQ_HZ,
.bus_hz = AIC_QSPI3_DEVICE_SPINOR_FREQ,
.dma_port_id = DMA_ID_SPI3,
.irq_num = QSPI3_IRQn,
.dl_width = AIC_QSPI3_BUS_WIDTH,
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
.cs_num = AIC_QSPI3_CS_NUM,
#endif
.rxd_dylmode = AIC_DEV_QSPI3_DELAY_MODE,
#if defined(AIC_QSPI_DRV_V20)
.txd_dylmode = AIC_DEV_QSPI3_TXD_DELAY_MODE,
.txc_dylmode = AIC_DEV_QSPI3_TX_CLK_DELAY_MODE,
#endif
},
#endif
};
int spi_write_read(struct aic_qspi_bus *qspi,
const uint8_t *write_buf, size_t write_size,
uint8_t *read_buf, size_t read_size)
{
struct qspi_transfer t;
int ret = 0;
u32 cs_num = 0;
hal_qspi_master_set_bus_width(&qspi->handle, HAL_QSPI_BUS_WIDTH_SINGLE);
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
cs_num = qspi->cs_num;
#endif
hal_qspi_master_set_cs(&qspi->handle, cs_num, true);
if (write_size) {
t.rx_data = NULL;
t.tx_data = (uint8_t *)write_buf;
t.data_len = write_size;
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
if (ret < 0)
goto out;
}
if (read_size) {
t.rx_data = read_buf;
t.tx_data = NULL;
t.data_len = read_size;
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
}
out:
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
cs_num = qspi->cs_num;
#endif
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
return ret;
}
static struct aic_qspi_bus *get_qspi_by_index(u32 idx)
{
struct aic_qspi_bus *qspi;
u32 i;
qspi = NULL;
for (i = 0; i < ARRAY_SIZE(qspi_bus_arr); i++) {
if (qspi_bus_arr[i].idx == idx) {
qspi = &qspi_bus_arr[i];
break;
}
}
return qspi;
}
struct aic_qspi_bus *qspi_probe(u32 spi_bus)
{
struct aic_qspi_bus *qspi;
int ret;
struct qspi_master_config cfg = {0};
qspi = get_qspi_by_index(spi_bus);
if (!qspi) {
pr_err("spi bus is invalid: %d\n", spi_bus);
return NULL;
}
if (qspi->probe_flag)
return qspi;
memset(&cfg, 0, sizeof(cfg));
cfg.idx = qspi->idx;
cfg.clk_in_hz = qspi->clk_in_hz;
cfg.clk_id = qspi->clk_id;
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_HIGH;
cfg.cpha = HAL_QSPI_CPHA_FIRST_EDGE;
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_LOW;
cfg.rx_dlymode = qspi->rxd_dylmode;
cfg.tx_dlymode = aic_convert_tx_dlymode(qspi->txc_dylmode, qspi->txd_dylmode);
ret = hal_qspi_master_init(&qspi->handle, &cfg);
if (ret) {
pr_err("hal_qspi_master_init failed. ret %d\n", ret);
return NULL;
}
#ifdef AIC_DMA_DRV
struct qspi_master_dma_config dmacfg;
memset(&dmacfg, 0, sizeof(dmacfg));
dmacfg.port_id = qspi->dma_port_id;
ret = hal_qspi_master_dma_config(&qspi->handle, &dmacfg);
if (ret) {
pr_err("qspi dma config failed.\n");
return NULL;
}
#endif
qspi->probe_flag = true;
return qspi;
}

View File

@@ -1,44 +1,237 @@
/*
* Copyright (C) 2023-2024 ArtInChip Technology Co.,Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: Dehuang Wu <dehuang.wu@artinchip.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <heap.h>
#include <aic_core.h>
#include "umm_malloc.h"
int heap_init(void *ptr, size_t size)
/* mem check */
#if defined(AIC_BOOTLOADER) && defined(AIC_BOOTLOADER_MEM_AUTO)
#if AIC_PSRAM_SIZE
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_PSRAM_BASE)
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_PSRAM_BASE
#endif
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_PSRAM_BASE + AIC_PSRAM_SIZE))
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_PSRAM_BASE + AIC_PSRAM_SIZE)
#endif
#elif AIC_DRAM_TOTAL_SIZE
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_DRAM_BASE)
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_DRAM_BASE
#endif
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_DRAM_BASE + AIC_DRAM_TOTAL_SIZE))
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_DRAM_BASE + AIC_DRAM_TOTAL_SIZE)
#endif
#elif AIC_SRAM_SIZE
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_SRAM_BASE)
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_SRAM_BASE
#endif
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_SRAM_BASE + AIC_SRAM_SIZE))
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_SRAM_BASE + AIC_SRAM_SIZE)
#endif
#elif AIC_SRAM_TOTAL_SIZE
#if (AIC_BOOTLOADER_TEXT_BASE < CPU_SRAM_BASE)
#error AIC_BOOTLOADER_TEXT_BASE less than CPU_SRAM_BASE
#endif
#if (AIC_BOOTLOADER_TEXT_BASE > (CPU_SRAM_BASE + AIC_SRAM_TOTAL_SIZE))
#error AIC_BOOTLOADER_TEXT_BASE more than (CPU_SRAM_BASE + AIC_SRAM_TOTAL_SIZE)
#endif
#endif
#endif
typedef struct {
char * name;
aic_mem_region_t type;
size_t start;
size_t end;
} heap_def_t;
static struct umm_heap_config heap[MAX_MEM_REGION];
static heap_def_t heap_def[MAX_MEM_REGION] = {
{
umm_init_heap(ptr, size);
.name = "sys",
.type = MEM_DEFAULT,
.start = (size_t)(&__heap_start),
.end = (size_t)(&__heap_end),
},
#if defined(AIC_BOOTLOADER) && defined(AIC_BOOTLOADER_MEM_AUTO)
{
.name = "reserved",
.type = MEM_RESERVED,
#if AIC_PSRAM_SIZE
.start = (size_t)(CPU_PSRAM_BASE),
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
#elif AIC_DRAM_TOTAL_SIZE
.start = (size_t)(CPU_DRAM_BASE),
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
#elif AIC_SRAM_SIZE || AIC_SRAM_TOTAL_SIZE
.start = (size_t)(CPU_SRAM_BASE),
.end = (size_t)(AIC_BOOTLOADER_TEXT_BASE - 0x100),
#endif
},
#endif
};
int heap_init(void)
{
int i = 0;
size_t start, end;
for (i = 0; i < MAX_MEM_REGION; i++) {
start = heap_def[i].start;
end = heap_def[i].end;
if (start >= end) {
pr_err("%s: region %d addr err. start = 0x%x, end = 0x%x\n", __func__, i, (u32)start, (u32)end);
return -1;
}
umm_init_heap(&heap[i], (void *)start, (end - start));
}
return 0;
}
#ifndef TLSF_MEM_HEAP
void *aic_tlsf_malloc(uint32_t mem_type, uint32_t nbytes)
void *aic_tlsf_malloc(u32 mem_type, u32 nbytes)
{
return umm_malloc(nbytes);
void *ptr;
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
void aic_tlsf_free(uint32_t mem_type, void *ptr)
{
umm_free(ptr);
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
ptr = umm_malloc(&heap[0], nbytes);
return ptr;
}
void *aic_tlsf_malloc_align(uint32_t mem_type, uint32_t size, uint32_t align)
{
return umm_malloc_align(size, align);
ptr = umm_malloc(&heap[i], nbytes);
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
return ptr;
}
void aic_tlsf_free_align(uint32_t mem_type, void *ptr)
void aic_tlsf_free(u32 mem_type, void *ptr)
{
umm_free_align(ptr);
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
void *aic_tlsf_realloc(uint32_t mem_type, void *ptr, uint32_t nbytes)
{
return umm_realloc(ptr, nbytes);
pr_debug("%s: ptr = 0x%x.\n", __func__, (u32)(uintptr_t)ptr);
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
umm_free(&heap[0], ptr);
return;
}
void *aic_tlsf_calloc(uint32_t mem_type, uint32_t count, uint32_t size)
umm_free(&heap[i], ptr);
}
void *aic_tlsf_malloc_align(u32 mem_type, u32 nbytes, u32 align)
{
return umm_calloc(count, size);
void *ptr;
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
ptr = umm_malloc_align(&heap[0], nbytes, align);
return ptr;
}
ptr = umm_malloc_align(&heap[i], nbytes, align);
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
return ptr;
}
void aic_tlsf_free_align(u32 mem_type, void *ptr)
{
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
pr_debug("%s: ptr = 0x%x.\n", __func__, (u32)(uintptr_t)ptr);
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
umm_free_align(&heap[0], ptr);
return;
}
umm_free_align(&heap[i], ptr);
}
void *aic_tlsf_realloc(u32 mem_type, void *ptr, u32 nbytes)
{
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
ptr = umm_realloc(&heap[0], ptr, nbytes);
return ptr;
}
ptr = umm_realloc(&heap[i], ptr, nbytes);
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
return ptr;
}
void *aic_tlsf_calloc(u32 mem_type, u32 count, u32 nbytes)
{
void *ptr;
int i = 0;
for (i = 0; i < sizeof(heap_def) / sizeof(heap_def_t); i++) {
if (heap_def[i].type == mem_type)
break;
}
if (i >= MAX_MEM_REGION) {
pr_debug("%s: not found mem type %d, use mem type 0.\n", __func__, mem_type);
ptr = umm_calloc(&heap[0], count, nbytes);
return ptr;
}
ptr = umm_calloc(&heap[i], count, nbytes);
pr_debug("%s: ptr = 0x%x, nbytes = 0x%x.\n", __func__, (u32)(uintptr_t)ptr, nbytes);
return ptr;
}
#endif

View File

@@ -19,13 +19,14 @@
#include <unistd.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <umm_malloc.h>
#include <aic_core.h>
#include <aic_tlsf.h>
void *_malloc_r(struct _reent *ptr, size_t size)
{
void* result;
result = (void*)umm_malloc(size);
result = (void*)aic_tlsf_malloc(MEM_DEFAULT, size);
if (result == NULL)
{
ptr->_errno = ENOMEM;
@@ -38,7 +39,7 @@ void *_realloc_r(struct _reent *ptr, void *old, size_t newlen)
{
void* result;
result = (void*)umm_realloc(old, newlen);
result = (void*)aic_tlsf_realloc(MEM_DEFAULT, old, newlen);
if (result == NULL)
{
ptr->_errno = ENOMEM;
@@ -51,7 +52,7 @@ void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
{
void* result;
result = (void*)umm_calloc(size, len);
result = (void*)aic_tlsf_calloc(MEM_DEFAULT, size, len);
if (result == NULL)
{
ptr->_errno = ENOMEM;
@@ -62,7 +63,7 @@ void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
void _free_r(struct _reent *ptr, void *addr)
{
umm_free(addr);
aic_tlsf_free(MEM_DEFAULT, addr);
}
int *__errno(void)

View File

@@ -34,6 +34,7 @@
* R.Hempel 2020-02-01 - Macro functions are uppercased - See Issue 34
* R.Hempel 2020-06-20 - Support alternate body size - See Issue 42
* R.Hempel 2021-05-02 - Support explicit memory umm_init_heap() - See Issue 53
* K.Whitlock 2023-07-06 - Add support for multiple heaps
* ----------------------------------------------------------------------------
*/
@@ -81,18 +82,9 @@ UMM_H_ATTPACKPRE typedef struct umm_block_t {
/* ------------------------------------------------------------------------- */
struct umm_heap_config {
umm_block *pheap;
size_t heap_size;
uint16_t numblocks;
};
struct umm_heap_config umm_heap_current;
// struct umm_heap_config umm_heaps[UMM_NUM_HEAPS];
#define UMM_HEAP (umm_heap_current.pheap)
#define UMM_HEAPSIZE (umm_heap_current.heap_size)
#define UMM_NUMBLOCKS (umm_heap_current.numblocks)
#define UMM_HEAP ((umm_block *)heap->pheap)
#define UMM_HEAPSIZE (heap->heap_size)
#define UMM_NUMBLOCKS (heap->numblocks)
#define UMM_BLOCKSIZE (sizeof(umm_block))
#define UMM_BLOCK_LAST (UMM_NUMBLOCKS - 1)
@@ -200,7 +192,8 @@ static uint16_t umm_blocks(size_t size) {
*
* Note that free pointers are NOT modified by this function.
*/
static void umm_split_block(uint16_t c,
static void umm_split_block(umm_heap *heap,
uint16_t c,
uint16_t blocks,
uint16_t new_freemask) {
@@ -213,7 +206,7 @@ static void umm_split_block(uint16_t c,
/* ------------------------------------------------------------------------ */
static void umm_disconnect_from_free_list(uint16_t c) {
static void umm_disconnect_from_free_list(umm_heap *heap, uint16_t c) {
/* Disconnect this block from the FREE list */
UMM_NFREE(UMM_PFREE(c)) = UMM_NFREE(c);
@@ -230,7 +223,7 @@ static void umm_disconnect_from_free_list(uint16_t c) {
* next block is free.
*/
static void umm_assimilate_up(uint16_t c) {
static void umm_assimilate_up(umm_heap *heap, uint16_t c) {
if (UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK) {
@@ -245,7 +238,7 @@ static void umm_assimilate_up(uint16_t c) {
/* Disconnect the next block from the FREE list */
umm_disconnect_from_free_list(UMM_NBLOCK(c));
umm_disconnect_from_free_list(heap, UMM_NBLOCK(c));
/* Assimilate the next block with this one */
@@ -260,7 +253,7 @@ static void umm_assimilate_up(uint16_t c) {
* up before assimilating down.
*/
static uint16_t umm_assimilate_down(uint16_t c, uint16_t freemask) {
static uint16_t umm_assimilate_down(umm_heap *heap, uint16_t c, uint16_t freemask) {
// We are going to assimilate down to the previous block because
// it was free, so remove it from the fragmentation metric
@@ -285,10 +278,10 @@ static uint16_t umm_assimilate_down(uint16_t c, uint16_t freemask) {
/* ------------------------------------------------------------------------- */
void umm_init_heap(void *ptr, size_t size)
void umm_init_heap(umm_heap *heap, void *ptr, size_t size)
{
/* init heap pointer and size, and memset it to 0 */
UMM_HEAP = (umm_block *)ptr;
heap->pheap = ptr;
UMM_HEAPSIZE = size;
UMM_NUMBLOCKS = (UMM_HEAPSIZE / UMM_BLOCKSIZE);
memset(UMM_HEAP, 0x00, UMM_HEAPSIZE);
@@ -337,10 +330,10 @@ void umm_init_heap(void *ptr, size_t size)
}
void umm_init(void) {
void umm_init(umm_heap *heap) {
/* Initialize the heap from linker supplied values */
umm_init_heap(UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE);
umm_init_heap(heap, UMM_MALLOC_CFG_HEAP_ADDR, UMM_MALLOC_CFG_HEAP_SIZE);
}
/* ------------------------------------------------------------------------
@@ -348,7 +341,7 @@ void umm_init(void) {
* UMM_CRITICAL_ENTRY(id) and UMM_CRITICAL_EXIT(id).
*/
static void umm_free_core(void *ptr) {
static void umm_free_core(umm_heap *heap, void *ptr) {
uint16_t c;
@@ -369,7 +362,7 @@ static void umm_free_core(void *ptr) {
/* Now let's assimilate this block with the next one if possible. */
umm_assimilate_up(c);
umm_assimilate_up(heap, c);
/* Then assimilate with the previous block if possible */
@@ -377,7 +370,7 @@ static void umm_free_core(void *ptr) {
DBGLOG_DEBUG("Assimilate down to previous block, which is FREE\n");
c = umm_assimilate_down(c, UMM_FREELIST_MASK);
c = umm_assimilate_down(heap, c, UMM_FREELIST_MASK);
} else {
/*
* The previous block is not a free block, so add this one to the head
@@ -398,7 +391,7 @@ static void umm_free_core(void *ptr) {
/* ------------------------------------------------------------------------ */
void umm_free(void *ptr) {
void umm_free(umm_heap *heap, void *ptr) {
UMM_CRITICAL_DECL(id_free);
UMM_CHECK_INITIALIZED();
@@ -411,11 +404,20 @@ void umm_free(void *ptr) {
return;
}
/* If we're being asked to free an out of range pointer - do nothing */
/* TODO: remove the check for NULL pointer later */
if ((ptr < heap->pheap) || ((size_t)ptr >= (size_t)heap->pheap + heap->heap_size)) {
DBGLOG_DEBUG("free an out of range pointer -> do nothing\n");
return;
}
/* Free the memory withing a protected critical section */
UMM_CRITICAL_ENTRY(id_free);
umm_free_core(ptr);
umm_free_core(heap, ptr);
UMM_CRITICAL_EXIT(id_free);
}
@@ -425,7 +427,7 @@ void umm_free(void *ptr) {
* UMM_CRITICAL_ENTRY(id) and UMM_CRITICAL_EXIT(id).
*/
static void *umm_malloc_core(size_t size) {
static void *umm_malloc_core(umm_heap *heap, size_t size) {
uint16_t blocks;
uint16_t blockSize = 0;
@@ -493,7 +495,7 @@ static void *umm_malloc_core(size_t size) {
/* Disconnect this block from the FREE list */
umm_disconnect_from_free_list(cf);
umm_disconnect_from_free_list(heap, cf);
} else {
/* It's not an exact fit and we need to split off a block. */
@@ -503,7 +505,7 @@ static void *umm_malloc_core(size_t size) {
* split current free block `cf` into two blocks. The first one will be
* returned to user, so it's not free, and the second one will be free.
*/
umm_split_block(cf, blocks, UMM_FREELIST_MASK /*new block is free*/);
umm_split_block(heap, cf, blocks, UMM_FREELIST_MASK /*new block is free*/);
UMM_FRAGMENTATION_METRIC_ADD(UMM_NBLOCK(cf));
@@ -536,7 +538,7 @@ static void *umm_malloc_core(size_t size) {
/* ------------------------------------------------------------------------ */
void *umm_malloc(size_t size) {
void *umm_malloc(umm_heap *heap, size_t size) {
UMM_CRITICAL_DECL(id_malloc);
void *ptr = NULL;
@@ -560,7 +562,7 @@ void *umm_malloc(size_t size) {
UMM_CRITICAL_ENTRY(id_malloc);
ptr = umm_malloc_core(size);
ptr = umm_malloc_core(heap, size);
UMM_CRITICAL_EXIT(id_malloc);
@@ -569,7 +571,7 @@ void *umm_malloc(size_t size) {
/* ------------------------------------------------------------------------ */
void *umm_realloc(void *ptr, size_t size) {
void *umm_realloc(umm_heap *heap, void *ptr, size_t size) {
UMM_CRITICAL_DECL(id_realloc);
uint16_t blocks;
@@ -594,7 +596,7 @@ void *umm_realloc(void *ptr, size_t size) {
if (((void *)NULL == ptr)) {
DBGLOG_DEBUG("realloc the NULL pointer - call malloc()\n");
return umm_malloc(size);
return umm_malloc(heap, size);
}
/*
@@ -606,7 +608,7 @@ void *umm_realloc(void *ptr, size_t size) {
if (0 == size) {
DBGLOG_DEBUG("realloc to 0 size, just free the block\n");
umm_free(ptr);
umm_free(heap, ptr);
return (void *)NULL;
}
@@ -698,20 +700,20 @@ void *umm_realloc(void *ptr, size_t size) {
// Case 2 - block + next block fits EXACTLY
} else if ((blockSize + nextBlockSize) == blocks) {
DBGLOG_DEBUG("exact realloc using next block - %i\n", blocks);
umm_assimilate_up(c);
umm_assimilate_up(heap, c);
blockSize += nextBlockSize;
// Case 3 - prev block NOT free and block + next block fits
} else if ((0 == prevBlockSize) && (blockSize + nextBlockSize) >= blocks) {
DBGLOG_DEBUG("realloc using next block - %i\n", blocks);
umm_assimilate_up(c);
umm_assimilate_up(heap, c);
blockSize += nextBlockSize;
// Case 4 - prev block + block fits
} else if ((prevBlockSize + blockSize) >= blocks) {
DBGLOG_DEBUG("realloc using prev block - %i\n", blocks);
umm_disconnect_from_free_list(UMM_PBLOCK(c));
c = umm_assimilate_down(c, 0);
umm_disconnect_from_free_list(heap, UMM_PBLOCK(c));
c = umm_assimilate_down(heap, c, 0);
memmove((void *)&UMM_DATA(c), ptr, curSize);
ptr = (void *)&UMM_DATA(c);
blockSize += prevBlockSize;
@@ -719,9 +721,9 @@ void *umm_realloc(void *ptr, size_t size) {
// Case 5 - prev block + block + next block fits
} else if ((prevBlockSize + blockSize + nextBlockSize) >= blocks) {
DBGLOG_DEBUG("realloc using prev and next block - %i\n", blocks);
umm_assimilate_up(c);
umm_disconnect_from_free_list(UMM_PBLOCK(c));
c = umm_assimilate_down(c, 0);
umm_assimilate_up(heap, c);
umm_disconnect_from_free_list(heap, UMM_PBLOCK(c));
c = umm_assimilate_down(heap, c, 0);
memmove((void *)&UMM_DATA(c), ptr, curSize);
ptr = (void *)&UMM_DATA(c);
blockSize += (prevBlockSize + nextBlockSize);
@@ -730,10 +732,10 @@ void *umm_realloc(void *ptr, size_t size) {
} else {
DBGLOG_DEBUG("realloc a completely new block %i\n", blocks);
void *oldptr = ptr;
if ((ptr = umm_malloc_core(size))) {
if ((ptr = umm_malloc_core(heap, size))) {
DBGLOG_DEBUG("realloc %i to a bigger block %i, copy, and free the old\n", blockSize, blocks);
memcpy(ptr, oldptr, curSize);
umm_free_core(oldptr);
umm_free_core(heap, oldptr);
} else {
DBGLOG_DEBUG("realloc %i to a bigger block %i failed - return NULL and leave the old block!\n", blockSize, blocks);
/* This space intentionally left blnk */
@@ -747,8 +749,8 @@ void *umm_realloc(void *ptr, size_t size) {
if (blockSize > blocks) {
DBGLOG_DEBUG("split and free %i blocks from %i\n", blocks, blockSize);
umm_split_block(c, blocks, 0);
umm_free_core((void *)&UMM_DATA(c + blocks));
umm_split_block(heap, c, blocks, 0);
umm_free_core(heap, (void *)&UMM_DATA(c + blocks));
}
/* Release the critical section... */
@@ -759,10 +761,10 @@ void *umm_realloc(void *ptr, size_t size) {
/* ------------------------------------------------------------------------ */
void *umm_calloc(size_t num, size_t item_size) {
void *umm_calloc(umm_heap *heap, size_t num, size_t item_size) {
void *ret;
ret = umm_malloc((size_t)(item_size * num));
ret = umm_malloc(heap, (size_t)(item_size * num));
if (ret) {
memset(ret, 0x00, (size_t)(item_size * num));
@@ -771,7 +773,7 @@ void *umm_calloc(size_t num, size_t item_size) {
return ret;
}
void *umm_malloc_align(size_t size, size_t align)
void *umm_malloc_align(umm_heap *heap, size_t size, size_t align)
{
void *ptr;
void *align_ptr;
@@ -788,7 +790,7 @@ void *umm_malloc_align(size_t size, size_t align)
/* get total aligned size */
align_size = ((size + uintptr_size) & ~uintptr_size) + align;
/* allocate memory block from heap */
ptr = umm_malloc(align_size);
ptr = umm_malloc(heap, align_size);
if (ptr != NULL) {
/* the allocated memory block is aligned */
if (((unsigned long)ptr & (align - 1)) == 0) {
@@ -807,7 +809,7 @@ void *umm_malloc_align(size_t size, size_t align)
return ptr;
}
void umm_free_align(void *ptr)
void umm_free_align(umm_heap *heap, void *ptr)
{
void *real_ptr;
@@ -815,6 +817,6 @@ void umm_free_align(void *ptr)
if (ptr == NULL)
return;
real_ptr = (void *)*(unsigned long *)((unsigned long)ptr - sizeof(void *));
umm_free(real_ptr);
umm_free(heap, real_ptr);
}
/* ------------------------------------------------------------------------ */

View File

@@ -16,15 +16,21 @@ extern "C" {
/* ------------------------------------------------------------------------ */
extern void umm_init_heap(void *ptr, size_t size);
extern void umm_init(void);
typedef struct umm_heap_config {
void *pheap;
size_t heap_size;
uint16_t numblocks;
} umm_heap;
extern void *umm_malloc(size_t size);
extern void *umm_calloc(size_t num, size_t size);
extern void *umm_realloc(void *ptr, size_t size);
extern void umm_free(void *ptr);
extern void *umm_malloc_align(size_t size, size_t align);
extern void umm_free_align(void *ptr);
extern void umm_init_heap(umm_heap *heap, void *ptr, size_t size);
extern void umm_init(umm_heap *heap);
extern void *umm_malloc(umm_heap *heap, size_t size);
extern void *umm_calloc(umm_heap *heap, size_t num, size_t size);
extern void *umm_realloc(umm_heap *heap, void *ptr, size_t size);
extern void umm_free(umm_heap *heap, void *ptr);
extern void *umm_malloc_align(umm_heap *heap, size_t size, size_t align);
extern void umm_free_align(umm_heap *heap, void *ptr);
/* ------------------------------------------------------------------------ */

View File

@@ -15,9 +15,6 @@ int hal_cir_init(aic_cir_ctrl_t *aic_cir_ctrl)
int ret = 0;
uint32_t reg_val;
aic_cir_ctrl->cir_base = CIR_BASE;
aic_cir_ctrl->irq_num = CIR_IRQn;
aic_cir_ctrl->clk_idx = CLK_CIR;
ret = hal_clk_enable_deassertrst(aic_cir_ctrl->clk_idx);
/* Set noise thresholld */
@@ -56,7 +53,7 @@ int hal_cir_set_tx_carrier(aic_cir_ctrl_t * aic_cir_ctrl,
{
uint32_t mod_clk, clk_div, carrier_high, carrier_low, val;
mod_clk = hal_clk_get_freq(CLK_CIR);
mod_clk = hal_clk_get_freq(aic_cir_ctrl->clk_idx);
if (protocol == 1) {
/* RC5 protocol */
clk_div = DIV_ROUND_UP(mod_clk, 36000);
@@ -79,7 +76,7 @@ void hal_cir_set_rx_sample_clock(aic_cir_ctrl_t * aic_cir_ctrl,
{
uint32_t mod_clk, clk_div;
mod_clk = hal_clk_get_freq(CLK_CIR);
mod_clk = hal_clk_get_freq(aic_cir_ctrl->clk_idx);
if (protocol == 1) {
/* RC5 protocol */
clk_div = DIV_ROUND_UP(mod_clk, 36000);

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2024, ArtInChip Technology CO.,LTD. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Chen JunLong <junlong.chen@artinchip.com>
*/
#include <string.h>
#include <aic_core.h>
#include <aic_hal.h>
#include <aic_log.h>
#include <hal_dce.h>
#include "aic_hal_clk.h"
int hal_dce_init(void)
{
int ret = 0;
ret = hal_clk_enable(CLK_DCE);
if (ret < 0) {
hal_log_err("Failed to enable DCE clk.\n");
return -EFAULT;
}
ret = hal_clk_enable_deassertrst(CLK_DCE);
if (ret < 0) {
hal_log_err("Failed to reset DCE deassert.\n");
return -EFAULT;
}
return 0;
}
void hal_dce_deinit(void)
{
hal_clk_disable(CLK_DCE);
hal_clk_disable_assertrst(CLK_DCE);
}
void hal_dce_checksum_start(u8 *data, u32 len)
{
writel((u32)data, DCE_ADDR_REG);
writel(len, DCE_LEN_REG);
writel(DCE_ALG_SUM, DCE_CFG_REG);
writel(0x1, DCE_CTL_REG);
}
u32 hal_dce_checksum_wait(void)
{
int ret = 0, cnt = 0;
u32 val;
while (1) {
val = readl(DCE_ISR_REG);
if (val & DCE_SUM_FINISH_MSK) {
ret = 0;
break;
}
if (val & DCE_ERR_ALL_MSK) {
ret = DCE_CALC_ERR;
break;
}
cnt++;
if (cnt >= DCE_WAIT_CNT) {
ret = DCE_CALC_TMO;
break;
}
aic_udelay(100);
}
/* Clear all status */
writel(0xFFFFFFFF, DCE_ISR_REG);
return ret;
}
u32 hal_dce_checksum_result(void)
{
return readl(DCE_SUM_RST_REG);
}
/*
* param u32 out_bit_in_word:OUTPUT_BIT_IN_WORD_REV 0 or 1
* param u32 input_bit_in_byte:INPUT_BIT_IN_BYTE_REV 0 or 1
* param u32 input_bit_in_word:INPUT_BIT_IN_WORD_REV 0 or 1
* param u32 input_byte_in_word:INPUT_BYTE_IN_WORD_REV 0 or 1
* return 0 success other failed
*/
void hal_dce_crc32_cfg(u32 out_bit_in_word, u32 input_bit_in_byte,
u32 input_bit_in_word, u32 input_byte_in_word)
{
u32 val = 0;
if (out_bit_in_word)
val |= OUTPUT_BIT_IN_WORD_REV;
if (input_bit_in_byte)
val |= INPUT_BIT_IN_BYTE_REV;
if (input_bit_in_word)
val |= INPUT_BIT_IN_WORD_REV;
if (input_byte_in_word)
val |= INPUT_BYTE_IN_WORD_REV;
writel(val, DCE_CRC_CFG_REG);
}
void hal_dce_crc32_xor_val(u32 val)
{
writel(val, DCE_CRC_XOROUT_REG);
}
void hal_dce_crc32_start(u32 crc, u8 *data, u32 len)
{
if (crc)
writel(crc, DCE_CRC_INIT_REG);
writel((u32)data, DCE_ADDR_REG);
writel(len, DCE_LEN_REG);
writel(DCE_ALG_CRC, DCE_CFG_REG);
writel(0x1, DCE_CTL_REG);
}
int hal_dce_crc32_wait(void)
{
int ret = 0, cnt = 0;
u32 val;
while (1) {
val = readl(DCE_ISR_REG);
if (val & DCE_CRC_FINISH_MSK) {
ret = 0;
break;
}
if (val & DCE_ERR_ALL_MSK) {
ret = DCE_CALC_ERR;
break;
}
cnt++;
if (cnt >= DCE_WAIT_CNT) {
ret = DCE_CALC_TMO;
break;
}
aic_udelay(100);
}
/* Clear all status */
writel(0xFFFFFFFF, DCE_ISR_REG);
return ret;
}
u32 hal_dce_crc32_result(void)
{
return readl(DCE_CRC_RST_REG);
}
u32 hal_get_version(void)
{
return readl(DCE_GET_VERSION_REG);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -12,28 +12,28 @@
#define CSC_COEFFS_NUM 12
static const unsigned int yuv2rgb_bt601[CSC_COEFFS_NUM] = {
0x04a8, 0x0000, 0x0662, 0x3212,
0x04a8, 0x1e70, 0x1cc0, 0x087a,
0x04a8, 0x0811, 0x0000, 0x2eb4
static const int yuv2rgb_bt601[CSC_COEFFS_NUM] = {
1192, 0, 1634, -3269,
1192, -401, -833, 2467,
1192, 2066, 0, -4131
};
static const unsigned int yuv2rgb_bt709[CSC_COEFFS_NUM] = {
0x04a8, 0x0000, 0x0722, 0x3093,
0x04a8, 0x1f27, 0x1ddf, 0x04ce,
0x04a8, 0x0873, 0x0000, 0x2df2
static const int yuv2rgb_bt709[CSC_COEFFS_NUM] = {
1192, 0, 1836, -3970,
1192, -218, -546, 1230,
1192, 2163, 0, -4624
};
static const unsigned int yuv2rgb_bt601_full[CSC_COEFFS_NUM] = {
0x0400, 0x0000, 0x059c, 0x34ca,
0x0400, 0x1ea1, 0x1d26, 0x0877,
0x0400, 0x0717, 0x0000, 0x31d4
static const int yuv2rgb_bt601_full[CSC_COEFFS_NUM] = {
1024, 0, 1436, -2871,
1024, -352, -731, 2167,
1024, 1815, 0, -3629
};
static const unsigned int yuv2rgb_bt709_full[CSC_COEFFS_NUM] = {
0x0400, 0x0000, 0x064d, 0x3368,
0x0400, 0x1f41, 0x1e22, 0x053e,
0x0400, 0x076c, 0x0000, 0x3129
static const int yuv2rgb_bt709_full[CSC_COEFFS_NUM] = {
1024, 0, 1613, -3225,
1024, -192, -479, 1342,
1024, 1900, 0, -3800
};
static const int rgb2yuv_bt601[CSC_COEFFS_NUM] = {
@@ -274,7 +274,7 @@ void ge_scaler0_enable(unsigned long base_addr, u32 enable)
void ge_set_csc_coefs(unsigned long base_addr, int color_space, u32 csc)
{
const u32 *coefs;
const int *coefs;
int i;
switch (color_space) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -381,8 +381,8 @@ static int check_bitblt(struct aic_ge_data *data, struct ge_bitblt *blt)
}
if (blt->src_buf.crop_en) {
if (src_rect->x < 0 ||
src_rect->y < 0 ||
if (src_rect->x < 0 || !src_rect->width ||
src_rect->y < 0 || !src_rect->height ||
src_rect->x >= src_size->width ||
src_rect->y >= src_size->height) {
hal_log_err("%s failed, invalid src crop\n",
@@ -392,8 +392,8 @@ static int check_bitblt(struct aic_ge_data *data, struct ge_bitblt *blt)
}
if (blt->dst_buf.crop_en) {
if (dst_rect->x < 0 ||
dst_rect->y < 0 ||
if (dst_rect->x < 0 || !dst_rect->width ||
dst_rect->y < 0 || !dst_rect->height ||
dst_rect->x >= dst_size->width ||
dst_rect->y >= dst_size->height) {
hal_log_err("%s failed, invalid dst crop\n",
@@ -402,6 +402,12 @@ static int check_bitblt(struct aic_ge_data *data, struct ge_bitblt *blt)
}
}
if (!src_size->width || !src_size->height ||
!dst_size->width || !dst_size->height) {
hal_log_err("Invalid size\n");
return -1;
}
if (!blt->src_buf.crop_en) {
src_rect->x = 0;
src_rect->y = 0;

View File

@@ -183,6 +183,52 @@ void hal_qspi_show_ists(u32 id, u32 sts)
printf(" ISTS_BIT_TDONE\n");
}
static void qspi_irq_tx_remain_handle(struct qspi_slave_state *qspi, u32 sts)
{
u32 base, total, free_len, dolen, imsk;
base = qspi_hw_index_to_base(qspi->idx);
if (qspi->async_tx) {
if (qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_CPU || qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_CPU) {
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
if (qspi->async_tx_remain) {
dolen = min(free_len, qspi->async_tx_remain);
qspi_hw_write_fifo(base, qspi->async_tx, dolen);
qspi->async_tx += dolen;
qspi->async_tx_wcnt += dolen;
qspi->async_tx_remain -= dolen;
} else {
imsk = ISTS_BIT_TF_EMP | ISTS_BIT_TF_RDY;
qspi_hw_interrupt_disable(base, imsk);
}
total = qspi->async_tx_remain + qspi->async_tx_wcnt;
qspi->async_tx_count = total - qspi_hw_get_tx_fifo_cnt(base);
if ((sts & ISTS_BIT_TDONE) && qspi_hw_get_tx_fifo_cnt(base))
qspi->async_tx_count -= 4;
}
}
}
static void qspi_irq_rx_remain_handle(struct qspi_slave_state *qspi, u32 sts)
{
u32 base, dolen;
base = qspi_hw_index_to_base(qspi->idx);
if (qspi->async_rx && qspi->async_rx_remain) {
if ((qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_CPU) || qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_CPU) {
dolen = qspi_hw_get_rx_fifo_cnt(base);
if (dolen > qspi->async_rx_remain)
dolen = qspi->async_rx_remain;
qspi_hw_read_fifo(base, qspi->async_rx, dolen);
qspi->async_rx += dolen;
qspi->async_rx_count += dolen;
qspi->async_rx_remain -= dolen;
}
}
}
void hal_qspi_slave_irq_handler(qspi_slave_handle *h)
{
struct qspi_slave_state *qspi;
@@ -197,53 +243,20 @@ void hal_qspi_slave_irq_handler(qspi_slave_handle *h)
if (sts & ISTS_BIT_TF_OVF)
qspi->status |= HAL_QSPI_STATUS_TX_OVER_FLOW;
if ((sts & ISTS_BIT_TF_EMP) || (sts & ISTS_BIT_TF_RDY)) {
u32 dolen, free_len;
if ((qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_CPU) &&
qspi->async_tx) {
u32 total;
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
if (qspi->async_tx_remain) {
dolen = min(free_len, qspi->async_tx_remain);
qspi_hw_write_fifo(base, qspi->async_tx, dolen);
qspi->async_tx += dolen;
qspi->async_tx_wcnt += dolen;
qspi->async_tx_remain -= dolen;
} else {
imsk = ISTS_BIT_TF_EMP | ISTS_BIT_TF_RDY;
qspi_hw_interrupt_disable(base, imsk);
}
total = qspi->async_tx_remain + qspi->async_tx_wcnt;
qspi->async_tx_count = total - qspi_hw_get_tx_fifo_cnt(base);
}
}
/* remain work handle in cpu copy */
if ((sts & ISTS_BIT_TF_EMP) || (sts & ISTS_BIT_TF_RDY) || (sts & ISTS_BIT_TDONE))
qspi_irq_tx_remain_handle(qspi, sts);
if ((sts & ISTS_BIT_RF_FUL) || (sts & ISTS_BIT_RF_RDY) || (sts & ISTS_BIT_TDONE))
qspi_irq_rx_remain_handle(qspi, sts);
if (sts & ISTS_BIT_RF_UDR)
qspi->status |= HAL_QSPI_STATUS_RX_UNDER_RUN;
if (sts & ISTS_BIT_RF_OVF)
if (sts & ISTS_BIT_RF_OVF) {
/* ignore the RF_OVF in tx. */
if (!(qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_CPU || qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_DMA))
qspi->status |= HAL_QSPI_STATUS_RX_OVER_FLOW;
if ((sts & ISTS_BIT_RF_FUL) || (sts & ISTS_BIT_RF_RDY) || (sts & ISTS_BIT_TDONE)) {
u32 dolen;
if ((qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_CPU) && qspi->async_rx &&
qspi->async_rx_remain) {
dolen = qspi_hw_get_rx_fifo_cnt(base);
if (dolen > qspi->async_rx_remain)
dolen = qspi->async_rx_remain;
qspi_hw_read_fifo(base, qspi->async_rx, dolen);
qspi->async_rx += dolen;
qspi->async_rx_count += dolen;
qspi->async_rx_remain -= dolen;
}
}
if ((sts & ISTS_BIT_TF_EMP) && (sts & ISTS_BIT_TDONE)) {
/* Write 4 bytes 0 to clear TX Buffer,
* Note:
* Every time user send new data, please reset TX FIFO
*/
u32 zeros = 0;
qspi_hw_write_fifo(base, (void *)&zeros, 4);
}
if (sts & ISTS_BIT_TDONE) {
if (qspi->status == HAL_QSPI_STATUS_IN_PROGRESS)
qspi->status = HAL_QSPI_STATUS_OK;
@@ -255,14 +268,12 @@ void hal_qspi_slave_irq_handler(qspi_slave_handle *h)
qspi_hw_interrupt_disable(base, imsk);
qspi->status |= HAL_QSPI_STATUS_ASYNC_TDONE;
if (QSPI_IS_ASYNC_ALL_DONE(qspi->status, qspi->done_mask)) {
if (qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_DMA) {
qspi->async_rx_count =
qspi->async_rx_remain - qspi_hw_get_idma_rx_len(base);
if (qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_DMA || qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_DMA) {
qspi->async_rx_count = qspi->async_rx_remain - qspi_hw_get_idma_rx_len(base);
aicos_dcache_invalid_range(qspi->async_rx, qspi->async_rx_count);
}
if (qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_DMA) {
qspi->async_tx_count =
qspi->async_tx_remain - qspi_hw_get_tx_fifo_cnt(base);
if (qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_DMA || qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_DMA) {
qspi->async_tx_count = qspi->async_tx_remain - qspi_hw_get_idma_tx_len(base);
}
if (qspi->cb)
qspi->cb(h, qspi->cb_priv);
@@ -275,6 +286,7 @@ int qspi_slave_transfer_cpu_async(struct qspi_slave_state *qspi,
struct qspi_transfer *t)
{
u32 base, txlen, rxlen;
u32 free_len, dolen;
int ret = 0;
base = qspi_hw_index_to_base(qspi->idx);
@@ -285,9 +297,39 @@ int qspi_slave_transfer_cpu_async(struct qspi_slave_state *qspi,
return -EINVAL;
qspi_hw_reset_fifo(base);
qspi_hw_ctrl_reset(base);
qspi_hw_interrupt_disable(base, ICR_BIT_ALL_MSK);
qspi->status = HAL_QSPI_STATUS_IN_PROGRESS;
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
if (qspi->bus_width != 1) {
hal_log_err("Full duplex mode did not support. bus width: %d\n", qspi->bus_width);
return -1;
}
qspi->work_mode = QSPI_WORK_MODE_ASYNC_DUPLEX_CPU;
qspi->done_mask = HAL_QSPI_STATUS_ASYNC_TDONE;
qspi->async_rx = t->rx_data;
qspi->async_rx_count = 0;
qspi->async_rx_remain = t->data_len;
qspi->async_tx = t->tx_data;
qspi->async_tx_count = 0;
qspi->async_tx_wcnt = 0;
qspi->async_tx_remain = t->data_len;
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
if (qspi->async_tx_remain) {
dolen = min(free_len, qspi->async_tx_remain);
qspi_hw_write_fifo(base, qspi->async_tx, dolen);
qspi->async_tx += dolen;
qspi->async_tx_wcnt += dolen;
qspi->async_tx_remain -= dolen;
}
qspi_hw_set_slave_output_en(base, 1);
qspi_hw_interrupt_enable(base, ICR_BIT_ERRS | ICR_BIT_TDONE_INTE |
ISTS_BIT_TF_RDY | ISTS_BIT_TF_EMP |
ICR_BIT_CS_INV_INTE);
qspi_hw_clear_interrupt_status(base, ISTS_BIT_ALL_MSK);
} else if (t->tx_data) {
txlen = t->data_len;
qspi->work_mode = QSPI_WORK_MODE_ASYNC_TX_CPU;
qspi->done_mask = HAL_QSPI_STATUS_ASYNC_TDONE;
@@ -298,6 +340,16 @@ int qspi_slave_transfer_cpu_async(struct qspi_slave_state *qspi,
qspi->async_tx_count = 0;
qspi->async_tx_wcnt = 0;
qspi->async_tx_remain = txlen;
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
if (qspi->async_tx_remain) {
dolen = min(free_len, qspi->async_tx_remain);
qspi_hw_write_fifo(base, qspi->async_tx, dolen);
qspi->async_tx += dolen;
qspi->async_tx_wcnt += dolen;
qspi->async_tx_remain -= dolen;
}
if (qspi->bus_width > 1)
qspi_hw_set_slave_output_en(base, 1);
else
@@ -338,10 +390,29 @@ static int qspi_slave_transfer_dma_async(struct qspi_slave_state *qspi, struct q
return -EINVAL;
qspi_hw_reset_fifo(base);
qspi_hw_ctrl_reset(base);
qspi_hw_set_idma_busrt_auto_len_en(base, 1);
qspi_hw_interrupt_disable(base, ICR_BIT_ALL_MSK);
qspi->status = HAL_QSPI_STATUS_IN_PROGRESS;
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
qspi->work_mode = QSPI_WORK_MODE_ASYNC_DUPLEX_DMA;
qspi->done_mask = HAL_QSPI_STATUS_ASYNC_TDONE;
qspi->async_tx_remain = t->data_len;
qspi->async_tx = t->tx_data;
qspi->async_rx = t->rx_data;
qspi_hw_set_slave_output_en(base, 1);
aicos_dcache_clean_range(qspi->async_tx, t->data_len);
qspi_hw_set_idma_tx_addr(base, (u32)t->tx_data);
qspi_hw_set_idma_tx_len(base, (u32)t->data_len);
qspi_hw_set_idma_tx_en(base, 1);
qspi->async_rx_remain = t->data_len;
qspi->async_rx = t->rx_data;
qspi_hw_set_idma_rx_addr(base, (u32)t->rx_data);
qspi_hw_set_idma_rx_len(base, (u32)t->data_len);
qspi_hw_set_idma_rx_en(base, 1);
qspi_hw_interrupt_enable(base, ICR_BIT_IDMA_MSK | ICR_BIT_CS_INV_INTE);
} else if (t->tx_data) {
qspi->work_mode = QSPI_WORK_MODE_ASYNC_TX_DMA;
qspi->done_mask = HAL_QSPI_STATUS_ASYNC_TDONE;
txlen = t->data_len;
@@ -353,7 +424,9 @@ static int qspi_slave_transfer_dma_async(struct qspi_slave_state *qspi, struct q
qspi_hw_set_idma_tx_addr(base, (u32)t->tx_data);
qspi_hw_set_idma_tx_len(base, (u32)txlen);
qspi_hw_set_idma_tx_en(base, 1);
qspi_hw_interrupt_enable(base, ICR_BIT_IDMA_MSK | ICR_BIT_CS_INV_INTE);
imsk = ICR_BIT_IDMA_MSK | ICR_BIT_CS_INV_INTE;
imsk &= ~ISTS_BIT_RF_OVF;
qspi_hw_interrupt_enable(base, imsk);
} else if (t->rx_data) {
qspi->work_mode = QSPI_WORK_MODE_ASYNC_RX_DMA;
qspi->done_mask = HAL_QSPI_STATUS_ASYNC_TDONE;
@@ -381,13 +454,12 @@ static int qspi_slave_can_dma(struct qspi_slave_state *qspi, struct qspi_transfe
return 0;
}
if (t->rx_data) {
/* RX: date length require 4 bytes alignment */
if (t->data_len & 0x3)
return 0;
/* Meet DMA's address align requirement */
if (((unsigned long)t->rx_data) & (AIC_DMA_ALIGN_SIZE - 1))
return 0;
}
if (t->data_len < QSPI_FIFO_DEPTH)
return 0;
return 1;
#else
return 0;
@@ -443,7 +515,9 @@ int hal_qspi_slave_transfer_count(qspi_slave_handle *h)
qspi = (struct qspi_slave_state *)h;
if ((qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_CPU) ||
(qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_DMA)) {
(qspi->work_mode == QSPI_WORK_MODE_ASYNC_RX_DMA) ||
(qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_CPU) ||
(qspi->work_mode == QSPI_WORK_MODE_ASYNC_DUPLEX_DMA)) {
return qspi->async_rx_count;
}
if ((qspi->work_mode == QSPI_WORK_MODE_ASYNC_TX_CPU) ||

View File

@@ -21,25 +21,6 @@
#include "qspi_hw_v1.0.h"
#endif
void qspi_reg_dump(u32 base)
{
u32 *p, i;
p = (void *)(unsigned long)base;
for (i = 0; i < 40; i++) {
if (i % 4 == 0)
printf("\n0x%lX : ", (unsigned long)p);
printf("%08X ", *p);
p++;
}
printf("\n");
}
void show_freq(char *msg, u32 id, u32 hz)
{
printf("qspi%d %s: %dHz\n", id, msg, hz);
}
void hal_qspi_master_bit_mode_init(u32 base)
{
#if AIC_SUPPORT_SPI_X_WIRE_IN_BIT_MODE == 4
@@ -243,60 +224,9 @@ int hal_qspi_master_set_cs(qspi_master_handle *h, u32 cs_num, bool enable)
return 0;
}
static u32 qspi_master_get_best_div_param(u32 sclk, u32 bus_hz, u32 *div)
{
u32 cdr1_clk, cdr2_clk;
int cdr2, cdr1;
/* Get the best cdr1 param if going to use cdr1 */
cdr1 = 0;
while ((sclk >> cdr1) > bus_hz)
cdr1++;
if (cdr1 > 0xF)
cdr1 = 0xF;
/* Get the best cdr2 param if going to use cdr2 */
cdr2 = (int)(sclk / (bus_hz * 2)) - 1;
if (cdr2 < 0)
cdr2 = 0;
if (cdr2 > 0xFF)
cdr2 = 0xFF;
cdr2_clk = sclk / (2 * cdr2 + 1);
cdr1_clk = sclk >> cdr1;
cdr2_clk = sclk / (2 * cdr2 + 1);
/* cdr1 param vs cdr2 param, use the best */
if (cdr1_clk == bus_hz) {
*div = cdr1;
return 0;
} else if (cdr2_clk == bus_hz) {
*div = cdr2;
return 1;
} else if ((cdr2_clk < bus_hz) && (cdr1_clk < bus_hz)) {
/* Two clks less than expect clk, use the larger one */
if (cdr2_clk > cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}
/*
* 1. Two clks great than expect clk, use least one
* 2. There is one clk less than expect clk, use it
*/
if (cdr2_clk < cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}
int hal_qspi_master_set_bus_freq(qspi_master_handle *h, u32 bus_hz)
{
u32 base, sclk, divider, div, cal_clk;
u32 base, sclk, divider, div, cal_clk = 0;
struct qspi_master_state *qspi;
CHECK_PARAM(h, -EINVAL);
@@ -359,6 +289,43 @@ int qspi_wait_transfer_done(u32 base, u32 tmo)
return 0;
}
int qspi_fifo_write_read(u32 base, u8 *tx, u8 *rx, u32 len, u32 tmo)
{
u32 free_len, dolen, cnt = 0;
while (len) {
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
while (free_len <= (QSPI_FIFO_DEPTH >> 3)) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
continue;
}
dolen = min(free_len, len);
qspi_hw_write_fifo(base, tx, dolen);
while (qspi_hw_get_rx_fifo_cnt(base) != dolen) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
}
qspi_hw_read_fifo(base, rx, dolen);
tx += dolen;
rx += dolen;
len -= dolen;
}
/* Data are written to FIFO, waiting all data are sent out */
while (qspi_hw_get_tx_fifo_cnt(base)) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
}
return 0;
}
int qspi_fifo_write_data(u32 base, u8 *data, u32 len, u32 tmo)
{
@@ -416,36 +383,12 @@ int qspi_fifo_read_data(u32 base, u8 *data, u32 len, u32 tmo)
return 0;
}
u32 qspi_calc_timeout(u32 bus_hz, u32 len)
{
u32 tmo_cnt, tmo_us;
u32 tmo_speed = 100;
if (bus_hz < HAL_QSPI_MIN_FREQ_HZ)
tmo_us = (1000000 * len * 8) / bus_hz;
else if (bus_hz < 1000000)
tmo_us = (1000 * len * 8) / (bus_hz / 1000);
else
tmo_us = (len * 8) / (bus_hz / 1000000);
/* Add 100ms time padding */
tmo_us += 100000;
tmo_cnt = tmo_us / HAL_QSPI_WAIT_PER_CYCLE;
/* Consider the speed limit of DMA or CPU copy.
*/
if (len >= QSPI_TRANSFER_DATA_LEN_1M)
tmo_speed = ((len / QSPI_CPU_DMA_MIN_SPEED_MS) + 1) * 1000;
return max(tmo_cnt, tmo_speed);
}
static int qspi_master_transfer_cpu_sync(qspi_master_handle *h,
struct qspi_transfer *t)
{
u32 base, tmo_cnt, txlen, tx_1line_cnt, rxlen, sts;
struct qspi_master_state *qspi;
int ret;
int ret = 0;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
@@ -463,7 +406,21 @@ static int qspi_master_transfer_cpu_sync(qspi_master_handle *h,
tmo_cnt *= 10;
qspi_hw_reset_fifo(base);
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
if (qspi_hw_get_bus_width(base) != QSPI_BUS_WIDTH_SINGLE) {
hal_log_err("Full duplex mode did not support.\n");
goto out;
}
qspi->work_mode = QSPI_WORK_MODE_SYNC_DUPLEX_CPU;
qspi_hw_set_transfer_cnt(base, t->data_len, t->data_len, 0, 0);
qspi_hw_drop_invalid_data(base, QSPI_RECV_ALL_INPUT_DATA);
qspi_hw_start_transfer(base);
ret = qspi_fifo_write_read(base, t->tx_data, t->rx_data, t->data_len, tmo_cnt);
if (ret < 0) {
hal_log_err("read write fifo failure.\n");
goto out;
}
} else if (t->tx_data) {
txlen = t->data_len;
tx_1line_cnt = 0;
if (qspi_hw_get_bus_width(base) == QSPI_BUS_WIDTH_SINGLE)
@@ -494,13 +451,14 @@ static int qspi_master_transfer_cpu_sync(qspi_master_handle *h,
goto out;
}
out:
qspi_hw_drop_invalid_data(base, QSPI_DROP_INVALID_DATA);
qspi_hw_get_interrupt_status(base, &sts);
qspi_hw_clear_interrupt_status(base, sts);
return ret;
}
#ifdef AIC_DMA_DRV
const u32 dynamic_dma_table[] = {
static const u32 dynamic_dma_table[] = {
#ifdef AIC_QSPI1_DYNAMIC_DMA
1,
#endif
@@ -617,6 +575,118 @@ static int qspi_master_wait_dma_done(struct aic_dma_chan *ch, u32 tmo)
return 0;
}
static int qspi_txrx_dma_sync(qspi_master_handle *h,
struct qspi_transfer *t, u32 tmo_cnt)
{
struct qspi_master_state *qspi;
struct dma_slave_config dmacfg;
u32 base;
int ret;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
qspi = (struct qspi_master_state *)h;
base = qspi_hw_index_to_base(qspi->idx);
if (qspi_hw_get_bus_width(base) != QSPI_BUS_WIDTH_SINGLE) {
hal_log_err("Full duplex mode did not support.\n");
return -1;
}
qspi->work_mode = QSPI_WORK_MODE_SYNC_DUPLEX_DMA;
qspi_hw_tx_dma_enable(base);
qspi_hw_rx_dma_enable(base);
qspi_hw_set_transfer_cnt(base, t->data_len, t->data_len, 0, 0);
qspi_hw_drop_invalid_data(base, QSPI_RECV_ALL_INPUT_DATA);
/* config tx DMA channel */
dmacfg.direction = DMA_MEM_TO_DEV;
dmacfg.slave_id = qspi->dma_cfg.port_id;
dmacfg.src_addr = (unsigned long)t->tx_data;
dmacfg.dst_addr = (unsigned long)QSPI_REG_TXD(base);
dmacfg.src_addr_width = qspi->dma_cfg.mem_bus_width;
dmacfg.src_maxburst = qspi->dma_cfg.mem_max_burst;
if (!(t->data_len % HAL_QSPI_DMA_4BYTES_LINE))
dmacfg.dst_addr_width = qspi->dma_cfg.dev_bus_width;
else
dmacfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dmacfg.dst_maxburst = qspi->dma_cfg.dev_max_burst;
ret = hal_dma_chan_config(qspi->dma_tx, &dmacfg);
if (ret < 0) {
hal_log_err("TX dma chan config failure.\n");
return -1;
}
ret = hal_dma_chan_prep_device(qspi->dma_tx, PTR2U32(QSPI_REG_TXD(base)),
PTR2U32(t->tx_data), t->data_len,
DMA_MEM_TO_DEV);
if (ret < 0) {
hal_log_err("TX dma chan prepare failure.\n");
return -1;
}
ret = hal_dma_chan_start(qspi->dma_tx);
if (ret < 0) {
hal_log_err("TX dma chan start failure.\n");
return -1;
}
/* config rx DMA channel */
dmacfg.direction = DMA_DEV_TO_MEM;
dmacfg.slave_id = qspi->dma_cfg.port_id;
dmacfg.src_addr = (unsigned long)QSPI_REG_RXD(base);
dmacfg.dst_addr = (unsigned long)t->rx_data;
if (!(t->data_len % HAL_QSPI_DMA_4BYTES_LINE))
dmacfg.src_addr_width = qspi->dma_cfg.dev_bus_width;
else
dmacfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dmacfg.src_maxburst = qspi->dma_cfg.mem_max_burst;
dmacfg.dst_addr_width = qspi->dma_cfg.dev_bus_width;
dmacfg.dst_maxburst = qspi->dma_cfg.dev_max_burst;
ret = hal_dma_chan_config(qspi->dma_rx, &dmacfg);
if (ret < 0) {
hal_log_err("RX dma chan config failure.\n");
return -1;
}
ret = hal_dma_chan_prep_device(qspi->dma_rx, PTR2U32(t->rx_data),
PTR2U32(QSPI_REG_RXD(base)), t->data_len,
DMA_DEV_TO_MEM);
if (ret < 0) {
hal_log_err("RX dma chan prepare failure.\n");
return -1;
}
ret = hal_dma_chan_start(qspi->dma_rx);
if (ret < 0) {
hal_log_err("RX dma chan start failure.\n");
return -1;
}
qspi_hw_start_transfer(base);
ret = qspi_wait_transfer_done(base, tmo_cnt);
if (ret < 0) {
hal_log_err("Wait transfer done timeout.\n");
}
ret = qspi_master_wait_dma_done(qspi->dma_rx, tmo_cnt);
if (ret < 0) {
hal_log_err("RX wait dma done timeout.\n");
}
qspi_hw_drop_invalid_data(base, QSPI_DROP_INVALID_DATA);
qspi_hw_rx_dma_disable(base);
qspi_hw_tx_dma_disable(base);
hal_dma_chan_stop(qspi->dma_rx);
hal_dma_chan_stop(qspi->dma_tx);
if (qspi_master_dynamic_dma(qspi)) {
hal_release_dma_chan(qspi->dma_tx);
hal_release_dma_chan(qspi->dma_rx);
}
return ret;
}
static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
struct qspi_transfer *t)
{
@@ -624,7 +694,7 @@ static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
struct qspi_master_state *qspi;
struct aic_dma_chan *dma_rx, *dma_tx;
struct dma_slave_config dmacfg;
int ret;
int ret = 0;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
@@ -641,7 +711,9 @@ static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
tmo_cnt = qspi_calc_timeout(qspi->bus_hz, t->data_len);
qspi_hw_reset_fifo(base);
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
ret = qspi_txrx_dma_sync(h, t, tmo_cnt);
} else if (t->tx_data) {
txlen = t->data_len;
tx_1line_cnt = 0;
if (qspi_hw_get_bus_width(base) == QSPI_BUS_WIDTH_SINGLE)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,25 +17,6 @@
#include "qspi_hw_v2.0.h"
void qspi_reg_dump(u32 base)
{
u32 *p, i;
p = (void *)(unsigned long)base;
for (i = 0; i < 40; i++) {
if (i % 4 == 0)
printf("\n0x%lX : ", (unsigned long)p);
printf("%08X ", *p);
p++;
}
printf("\n");
}
void show_freq(char *msg, u32 id, u32 hz)
{
printf("qspi%d %s: %dHz\n", id, msg, hz);
}
void hal_qspi_master_bit_mode_init(u32 base)
{
#if AIC_SUPPORT_SPI_X_WIRE_IN_BIT_MODE == 4
@@ -276,57 +257,6 @@ int hal_qspi_master_set_cs(qspi_master_handle *h, u32 cs_num, bool enable)
return 0;
}
static u32 qspi_master_get_best_div_param(u32 sclk, u32 bus_hz, u32 *div)
{
u32 cdr1_clk, cdr2_clk;
int cdr2, cdr1;
/* Get the best cdr1 param if going to use cdr1 */
cdr1 = 0;
while ((sclk >> cdr1) > bus_hz)
cdr1++;
if (cdr1 > 0xF)
cdr1 = 0xF;
/* Get the best cdr2 param if going to use cdr2 */
cdr2 = (int)(sclk / (bus_hz * 2)) - 1;
if (cdr2 < 0)
cdr2 = 0;
if (cdr2 > 0xFF)
cdr2 = 0xFF;
cdr2_clk = sclk / (2 * cdr2 + 1);
cdr1_clk = sclk >> cdr1;
cdr2_clk = sclk / (2 * cdr2 + 1);
/* cdr1 param vs cdr2 param, use the best */
if (cdr1_clk == bus_hz) {
*div = cdr1;
return 0;
} else if (cdr2_clk == bus_hz) {
*div = cdr2;
return 1;
} else if ((cdr2_clk < bus_hz) && (cdr1_clk < bus_hz)) {
/* Two clks less than expect clk, use the larger one */
if (cdr2_clk > cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}
/*
* 1. Two clks great than expect clk, use least one
* 2. There is one clk less than expect clk, use it
*/
if (cdr2_clk < cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}
int hal_qspi_master_set_bus_freq(qspi_master_handle *h, u32 bus_hz)
{
u32 base, sclk, divider, div;
@@ -427,6 +357,44 @@ int qspi_wait_gpdma_rx_done(u32 base, u32 tmo)
}
#endif
int qspi_fifo_write_read(u32 base, u8 *tx, u8 *rx, u32 len, u32 tmo)
{
u32 free_len, dolen, cnt = 0;
while (len) {
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
while (free_len <= (QSPI_FIFO_DEPTH >> 3)) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
free_len = QSPI_FIFO_DEPTH - qspi_hw_get_tx_fifo_cnt(base);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
continue;
}
dolen = min(free_len, len);
qspi_hw_write_fifo(base, tx, dolen);
while (qspi_hw_get_rx_fifo_cnt(base) != dolen) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
}
qspi_hw_read_fifo(base, rx, dolen);
tx += dolen;
rx += dolen;
len -= dolen;
}
/* Data are written to FIFO, waiting all data are sent out */
while (qspi_hw_get_tx_fifo_cnt(base)) {
aic_udelay(HAL_QSPI_WAIT_DELAY_US);
cnt++;
if (cnt > tmo)
return -ETIMEDOUT;
}
return 0;
}
int qspi_fifo_write_data(u32 base, u8 *data, u32 len, u32 tmo)
{
u32 dolen, free_len, cnt = 0;
@@ -483,36 +451,12 @@ int qspi_fifo_read_data(u32 base, u8 *data, u32 len, u32 tmo)
return 0;
}
u32 qspi_calc_timeout(u32 bus_hz, u32 len)
{
u32 tmo_cnt, tmo_us;
u32 tmo_speed = 100;
if (bus_hz < HAL_QSPI_MIN_FREQ_HZ)
tmo_us = (1000000 * len * 8) / bus_hz;
else if (bus_hz < 1000000)
tmo_us = (1000 * len * 8) / (bus_hz / 1000);
else
tmo_us = (len * 8) / (bus_hz / 1000000);
/* Add 100ms time padding */
tmo_us += 100000;
tmo_cnt = tmo_us / HAL_QSPI_WAIT_PER_CYCLE;
/* Consider the speed limit of DMA or CPU copy.
*/
if (len >= QSPI_TRANSFER_DATA_LEN_1M)
tmo_speed = ((len / QSPI_CPU_DMA_MIN_SPEED_MS) + 1) * 1000;
return max(tmo_cnt, tmo_speed);
}
static int qspi_master_transfer_cpu_sync(qspi_master_handle *h,
struct qspi_transfer *t)
{
u32 base, tmo_cnt, txlen, tx_1line_cnt, rxlen, sts;
struct qspi_master_state *qspi;
int ret;
int ret = 0;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
@@ -530,7 +474,21 @@ static int qspi_master_transfer_cpu_sync(qspi_master_handle *h,
tmo_cnt *= 10;
qspi_hw_reset_fifo(base);
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
if (qspi_hw_get_bus_width(base) != QSPI_BUS_WIDTH_SINGLE) {
hal_log_err("Full duplex mode did not support.\n");
goto out;
}
qspi->work_mode = QSPI_WORK_MODE_SYNC_DUPLEX_CPU;
qspi_hw_set_transfer_cnt(base, t->data_len, t->data_len, 0, 0);
qspi_hw_drop_invalid_data(base, QSPI_RECV_ALL_INPUT_DATA);
qspi_hw_start_transfer(base);
ret = qspi_fifo_write_read(base, t->tx_data, t->rx_data, t->data_len, tmo_cnt);
if (ret < 0) {
hal_log_err("read write fifo failure.\n");
goto out;
}
} else if (t->tx_data) {
txlen = t->data_len;
tx_1line_cnt = 0;
if (qspi_hw_get_bus_width(base) == QSPI_BUS_WIDTH_SINGLE)
@@ -581,6 +539,115 @@ static int qspi_master_wait_dma_done(struct aic_dma_chan *ch, u32 tmo)
return 0;
}
static int qspi_txrx_dma_sync(qspi_master_handle *h,
struct qspi_transfer *t, u32 tmo_cnt)
{
struct qspi_master_state *qspi;
struct dma_slave_config dmacfg;
u32 base;
int ret;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
qspi = (struct qspi_master_state *)h;
base = qspi_hw_index_to_base(qspi->idx);
if (qspi_hw_get_bus_width(base) != QSPI_BUS_WIDTH_SINGLE) {
hal_log_err("Full duplex mode did not support.\n");
return -1;
}
qspi->work_mode = QSPI_WORK_MODE_SYNC_DUPLEX_DMA;
qspi_hw_tx_dma_enable(base);
qspi_hw_rx_dma_enable(base);
qspi_hw_set_transfer_cnt(base, t->data_len, t->data_len, 0, 0);
qspi_hw_drop_invalid_data(base, QSPI_RECV_ALL_INPUT_DATA);
/* config tx DMA channel */
dmacfg.direction = DMA_MEM_TO_DEV;
dmacfg.slave_id = qspi->dma_cfg.port_id;
dmacfg.src_addr = (unsigned long)t->tx_data;
dmacfg.dst_addr = (unsigned long)QSPI_REG_TXD(base);
dmacfg.src_addr_width = qspi->dma_cfg.mem_bus_width;
dmacfg.src_maxburst = qspi->dma_cfg.mem_max_burst;
if (!(t->data_len % HAL_QSPI_DMA_4BYTES_LINE))
dmacfg.dst_addr_width = qspi->dma_cfg.dev_bus_width;
else
dmacfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dmacfg.dst_maxburst = qspi->dma_cfg.dev_max_burst;
ret = hal_dma_chan_config(qspi->dma_tx, &dmacfg);
if (ret < 0) {
hal_log_err("TX dma chan config failure.\n");
return -1;
}
ret = hal_dma_prep_mode_device(qspi->dma_tx, PTR2U32(QSPI_REG_TXD(base)),
PTR2U32(t->tx_data), t->data_len,
DMA_MEM_TO_DEV, TYPE_IO_FAST);
if (ret < 0) {
hal_log_err("TX dma chan prepare failure.\n");
return -1;
}
ret = hal_dma_chan_start(qspi->dma_tx);
if (ret < 0) {
hal_log_err("TX dma chan start failure.\n");
return -1;
}
/* config rx DMA channel */
dmacfg.direction = DMA_DEV_TO_MEM;
dmacfg.slave_id = qspi->dma_cfg.port_id;
dmacfg.src_addr = (unsigned long)QSPI_REG_RXD(base);
dmacfg.dst_addr = (unsigned long)t->rx_data;
if (!(t->data_len % HAL_QSPI_DMA_4BYTES_LINE))
dmacfg.src_addr_width = qspi->dma_cfg.dev_bus_width;
else
dmacfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dmacfg.src_maxburst = qspi->dma_cfg.mem_max_burst;
dmacfg.dst_addr_width = qspi->dma_cfg.dev_bus_width;
dmacfg.dst_maxburst = qspi->dma_cfg.dev_max_burst;
ret = hal_dma_chan_config(qspi->dma_rx, &dmacfg);
if (ret < 0) {
hal_log_err("RX dma chan config failure.\n");
return -1;
}
ret = hal_dma_prep_mode_device(qspi->dma_rx, PTR2U32(t->rx_data),
PTR2U32(QSPI_REG_RXD(base)), t->data_len,
DMA_DEV_TO_MEM, TYPE_IO_FAST);
if (ret < 0) {
hal_log_err("RX dma chan prepare failure.\n");
return -1;
}
ret = hal_dma_chan_start(qspi->dma_rx);
if (ret < 0) {
hal_log_err("RX dma chan start failure.\n");
return -1;
}
qspi_hw_start_transfer(base);
ret = qspi_wait_transfer_done(base, tmo_cnt);
if (ret < 0) {
hal_log_err("Wait transfer done timeout.\n");
}
ret = qspi_master_wait_dma_done(qspi->dma_rx, tmo_cnt);
if (ret < 0) {
hal_log_err("RX wait dma done timeout.\n");
}
qspi_hw_drop_invalid_data(base, QSPI_DROP_INVALID_DATA);
qspi_hw_rx_dma_disable(base);
qspi_hw_tx_dma_disable(base);
hal_dma_chan_stop(qspi->dma_rx);
hal_dma_chan_stop(qspi->dma_tx);
return ret;
}
static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
struct qspi_transfer *t)
{
@@ -588,7 +655,7 @@ static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
struct qspi_master_state *qspi;
struct aic_dma_chan *dma_rx, *dma_tx;
struct dma_slave_config dmacfg;
int ret;
int ret = 0;
CHECK_PARAM(h, -EINVAL);
CHECK_PARAM(t, -EINVAL);
@@ -605,7 +672,9 @@ static int qspi_master_transfer_dma_sync(qspi_master_handle *h,
tmo_cnt = qspi_calc_timeout(qspi->bus_hz, t->data_len);
qspi_hw_reset_fifo(base);
if (t->tx_data) {
if (t->tx_data && t->rx_data) {
ret = qspi_txrx_dma_sync(h, t, tmo_cnt);
} else if (t->tx_data) {
txlen = t->data_len;
tx_1line_cnt = 0;
if (qspi_hw_get_bus_width(base) == QSPI_BUS_WIDTH_SINGLE)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -444,6 +444,15 @@ static inline void qspi_hw_drop_invalid_data(u32 base, bool drop)
writel(val, QSPI_REG_TCFG(base));
}
static inline void qspi_hw_ctrl_reset(u32 base)
{
u32 val;
val = readl(QSPI_REG_CFG(base));
val |= CFG_BIT_CTRL_RST_MSK;
writel(val, QSPI_REG_CFG(base));
}
static inline void qspi_hw_reset_fifo(u32 base)
{
u32 val = readl(QSPI_REG_FCTL(base));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -595,6 +595,15 @@ static inline void qspi_hw_drop_invalid_data(u32 base, bool drop)
writel(val, QSPI_REG_TCFG(base));
}
static inline void qspi_hw_ctrl_reset(u32 base)
{
u32 val;
val = readl(QSPI_REG_CFG(base));
val |= CFG_BIT_CTRL_RST_MSK;
writel(val, QSPI_REG_CFG(base));
}
static inline void qspi_hw_reset_fifo(u32 base)
{
u32 val = readl(QSPI_REG_FCTL(base));

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Jiji Chen <jiji.chen@artinchip.com>
*/
#include <rtconfig.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <aic_core.h>
#include <hal_qspi.h>
#include "qspi_internal.h"
void qspi_reg_dump(u32 base)
{
u32 *p, i;
p = (void *)(unsigned long)base;
for (i = 0; i < 40; i++) {
if (i % 4 == 0)
printf("\n0x%lX : ", (unsigned long)p);
printf("%08X ", *p);
p++;
}
printf("\n");
}
void show_freq(char *msg, u32 id, u32 hz)
{
printf("qspi%d %s: %dHz\n", id, msg, hz);
}
u32 qspi_calc_timeout(u32 bus_hz, u32 len)
{
u32 tmo_cnt, tmo_us;
u32 tmo_speed = 100;
if (bus_hz < HAL_QSPI_MIN_FREQ_HZ)
tmo_us = (1000000 * len * 8) / bus_hz;
else if (bus_hz < 1000000)
tmo_us = (1000 * len * 8) / (bus_hz / 1000);
else
tmo_us = (len * 8) / (bus_hz / 1000000);
/* Add 100ms time padding */
tmo_us += 100000;
tmo_cnt = tmo_us / HAL_QSPI_WAIT_PER_CYCLE;
/* Consider the speed limit of DMA or CPU copy.
*/
if (len >= QSPI_TRANSFER_DATA_LEN_1M)
tmo_speed = ((len / QSPI_CPU_DMA_MIN_SPEED_MS) + 1) * 1000;
return max(tmo_cnt, tmo_speed);
}
u32 qspi_master_get_best_div_param(u32 sclk, u32 bus_hz, u32 *div)
{
u32 cdr1_clk, cdr2_clk;
int cdr2, cdr1;
/* Get the best cdr1 param if going to use cdr1 */
cdr1 = 0;
while ((sclk >> cdr1) > bus_hz)
cdr1++;
if (cdr1 > 0xF)
cdr1 = 0xF;
/* Get the best cdr2 param if going to use cdr2 */
cdr2 = (int)(sclk / (bus_hz * 2)) - 1;
if (cdr2 < 0)
cdr2 = 0;
if (cdr2 > 0xFF)
cdr2 = 0xFF;
cdr2_clk = sclk / (2 * cdr2 + 1);
cdr1_clk = sclk >> cdr1;
cdr2_clk = sclk / (2 * cdr2 + 1);
/* cdr1 param vs cdr2 param, use the best */
if (cdr1_clk == bus_hz) {
*div = cdr1;
return 0;
} else if (cdr2_clk == bus_hz) {
*div = cdr2;
return 1;
} else if ((cdr2_clk < bus_hz) && (cdr1_clk < bus_hz)) {
/* Two clks less than expect clk, use the larger one */
if (cdr2_clk > cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}
/*
* 1. Two clks great than expect clk, use least one
* 2. There is one clk less than expect clk, use it
*/
if (cdr2_clk < cdr1_clk) {
*div = cdr2;
return 1;
}
*div = cdr1;
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,6 +19,10 @@ extern "C" {
#define QSPI_WORK_MODE_ASYNC_TX_CPU 3
#define QSPI_WORK_MODE_ASYNC_RX_DMA 4
#define QSPI_WORK_MODE_ASYNC_TX_DMA 5
#define QSPI_WORK_MODE_SYNC_DUPLEX_CPU 6
#define QSPI_WORK_MODE_SYNC_DUPLEX_DMA 7
#define QSPI_WORK_MODE_ASYNC_DUPLEX_CPU 8
#define QSPI_WORK_MODE_ASYNC_DUPLEX_DMA 9
#define HAL_QSPI_STATUS_INTERNAL_MSK (0xFFFFUL << 16)
#define HAL_QSPI_STATUS_ASYNC_TDONE (0x1UL << 16)
@@ -30,13 +34,14 @@ extern "C" {
#define QSPI_TRANSFER_DATA_LEN_1M 0x100000
#define QSPI_CPU_DMA_MIN_SPEED_MS (0x800000 >> 10)
void qspi_reg_dump(u32 base);
void show_freq(char *msg, u32 id, u32 hz);
void hal_qspi_fifo_reset(u32 base, u32 fifo);
void hal_qspi_show_ists(u32 id, u32 sts);
u32 qspi_calc_timeout(u32 bus_hz, u32 len);
u32 qspi_master_get_best_div_param(u32 sclk, u32 bus_hz, u32 *div);
int qspi_fifo_write_data(u32 base, u8 *data, u32 len, u32 tmo);
int qspi_fifo_read_data(u32 base, u8 *data, u32 len, u32 tmo_us);
int qspi_wait_transfer_done(u32 base, u32 tmo);
u32 qspi_calc_timeout(u32 bus_hz, u32 len);
#ifdef __cplusplus
}

View File

@@ -31,6 +31,7 @@ extern "C" {
#include "usb_drv.h"
#endif
#include "wdt.h"
#include "gpai.h"
#ifdef __cplusplus
}

View File

@@ -1,10 +1,11 @@
/*
* Copyright (c) 2024, Artinchip Technology Co., Ltd
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Li Siyao <siyao.li@artinchip.com>
* Authors: Siyao Li <siyao.li@artinchip.com>
*/
#include "hal_gpai.h"
struct aic_gpai_ch aic_gpai_chs[] = {
#ifdef AIC_USING_GPAI0

View File

@@ -1,7 +1,9 @@
/*
* Copyright (c) 2023, Artinchip Technology Co., Ltd
* Copyright (C) 2023-2024 ArtInChip Technology Co.,Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: Dehuang Wu <dehuang.wu@artinchip.com>
*/
#ifndef __BL_HEAP_H_
@@ -11,7 +13,7 @@
extern "C" {
#endif
int heap_init(void *ptr, size_t size);
int heap_init(void);
#ifdef __cplusplus
}

View File

@@ -24,7 +24,7 @@
#define AUDIO_TRANSFER_TYPE_AMIC 6
#define MAX_VOLUME_0DB 160
#define AIC_AMIC_DEF_VAL 220
#define AIC_AMIC_DEF_VAL 200
struct aic_audio_config
{

View File

@@ -190,7 +190,7 @@
#define ADC_CTL2_REG (0xA4)
#define ADC_CTL2_MBIAS_CTL (8)
#define ADC_CTL2_PGA_GAIN_SEL (0xA)
#define ADC_CTL2_PGA_GAIN_SEL (0xF)
#define ADC_CTL2_PGA_GAIN_MASK GENMASK(3, 0)
#define DEFAULT_AUDIO_FREQ (24576000)

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024, ArtInChip Technology CO.,LTD. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Chen JunLong <junlong.chen@artinchip.com>
*/
#ifndef _AIC_HAL_DCE_H_
#define _AIC_HAL_DCE_H_
#include <aic_common.h>
#include <aic_soc.h>
#define DCE_CTL_REG (DCE_BASE + 0x000)
#define DCE_CFG_REG (DCE_BASE + 0x004)
#define DCE_IRQ_REG (DCE_BASE + 0x008)
#define DCE_ISR_REG (DCE_BASE + 0x00C)
#define DCE_ADDR_REG (DCE_BASE + 0x010)
#define DCE_LEN_REG (DCE_BASE + 0x014)
#define DCE_RST_REG (DCE_BASE + 0x040)
#define DCE_CRC_CFG_REG (DCE_BASE + 0x080)
#define DCE_CRC_INIT_REG (DCE_BASE + 0x084)
#define DCE_CRC_XOROUT_REG (DCE_BASE + 0x088)
#define DCE_CRC_RST_REG (DCE_BASE + 0x0C0)
#define DCE_SUM_RST_REG (DCE_BASE + 0x140)
#define DCE_GET_VERSION_REG (DCE_BASE + 0xFFC)
#define DCE_WAIT_CNT 10000
#define DCE_CALC_OK 0
#define DCE_CALC_ERR -1
#define DCE_CALC_TMO -2
#define DCE_ALG_CRC 0x1
#define DCE_ALG_SUM 0x2
#define DCE_ERR_ALL_MSK 0x07000000
#define DCE_CRC_FINISH_MSK 0x01
#define DCE_SUM_FINISH_MSK 0x02
#define OUTPUT_BIT_IN_WORD_REV (0x1 << 0)
#define INPUT_BIT_IN_BYTE_REV (0x1 << 1)
#define INPUT_BIT_IN_WORD_REV (0x1 << 2)
#define INPUT_BYTE_IN_WORD_REV (0x1 << 3)
int hal_dce_init(void);
void hal_dce_deinit(void);
void hal_dce_checksum_start(u8 *data, u32 len);
u32 hal_dce_checksum_wait(void);
u32 hal_dce_checksum_result(void);
void hal_dce_crc32_cfg(u32 out_bit_in_word, u32 input_bit_in_byte,
u32 input_bit_in_word, u32 input_byte_in_word);
void hal_dce_crc32_xor_val(u32 val);
void hal_dce_crc32_start(u32 crc, u8 *data, u32 len);
int hal_dce_crc32_wait(void);
u32 hal_dce_crc32_result(void);
u32 hal_get_version(void);
#endif

View File

@@ -93,9 +93,7 @@ struct aic_dma_task {
*/
struct aic_dma_task *v_next;
};
#endif
#ifdef AIC_DMA_DRV_V20
#else
struct aic_dma_task {
u32 link_id;
u32 cfg1; /* dma transfer configuration */
@@ -168,12 +166,6 @@ int hal_dma_chan_start(struct aic_dma_chan *chan);
int hal_dma_chan_stop(struct aic_dma_chan *chan);
int hal_dma_chan_pause(struct aic_dma_chan *chan);
int hal_dma_chan_resume(struct aic_dma_chan *chan);
#if defined(AIC_DMA_DRV_V20)
int hal_dma_chan_link_pause(struct aic_dma_chan *chan);
int hal_dma_chan_abandon(struct aic_dma_chan *chan);
int hal_dma_chan_wb_enable(struct aic_dma_chan *chan,
u32 src_addr, u32 dst_addr);
#endif
int hal_dma_chan_terminate_all(struct aic_dma_chan *chan);
int hal_dma_chan_register_cb(struct aic_dma_chan *chan,
dma_async_callback callback,

View File

@@ -207,6 +207,8 @@ enum i2c_slave_event {
#define I2C_7BIT_ADDR 0
#define I2C_10BIT_ADDR 1
#define I2C_MAX_CHAN 8
#define I2C_INTR_MASTER_MASK (I2C_INTR_RX_UNDER |\
I2C_INTR_RX_FULL |\
I2C_INTR_TX_EMPTY |\
@@ -224,6 +226,10 @@ static inline void hal_i2c_module_enable(aic_i2c_ctrl *i2c_dev)
{
uint32_t reg_val;
reg_val = readl(i2c_dev->reg_base + I2C_CTL);
reg_val |= I2C_CTL_RESTART_ENABLE;
writel(reg_val, i2c_dev->reg_base + I2C_CTL);
reg_val = readl(i2c_dev->reg_base + I2C_ENABLE);
reg_val |= I2C_ENABLE_BIT | I2C_SDA_STUCK_RECOVERY_ENABLE;
writel(reg_val, i2c_dev->reg_base + I2C_ENABLE);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -249,6 +249,8 @@ int hal_qspi_slave_transfer_abort(qspi_slave_handle *h);
int hal_qspi_slave_transfer_count(qspi_slave_handle *h);
void hal_qspi_slave_fifo_reset(qspi_slave_handle *h, u32 fifo);
void hal_qspi_show_ists(u32 id, u32 sts);
#endif //AIC_QSPI_DRV_V11
int hal_qspi_master_init(qspi_master_handle *h, struct qspi_master_config *cfg);
@@ -263,6 +265,10 @@ int hal_qspi_master_transfer_async(qspi_master_handle *h, struct qspi_transfer *
int hal_qspi_master_get_status(qspi_master_handle *h);
void hal_qspi_master_irq_handler(qspi_master_handle *h);
void hal_qspi_master_fifo_reset(qspi_master_handle *h, u32 fifo);
void hal_qspi_fifo_reset(u32 base, u32 fifo);
int hal_spi_master_transfer_sync(qspi_master_handle *h, struct qspi_transfer *t);
int hal_spi_master_transfer_async(qspi_master_handle *h, struct qspi_transfer *t);
int hal_qspi_master_transfer_bit_mode(qspi_master_handle *h, struct qspi_bm_transfer *t);

View File

@@ -36,6 +36,16 @@ config CPU_BASE
default 0xE0000000 if QEMU_RUN
depends on AIC_CHIP_D12X
config CPU_PSRAM_BASE
hex
default 0x40000000
depends on AIC_CHIP_D12X
config CPU_SRAM_BASE
hex
default 0x30040000
depends on AIC_CHIP_D12X
#--------------------------------------------
# cmu driver global option
#--------------------------------------------

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_gpio_id.h>
const int aic_gpio_groups_list[] = {
PA_GROUP,
PB_GROUP,
PC_GROUP,
PD_GROUP,
PE_GROUP,
};
const int aic_gpio_group_size = sizeof(aic_gpio_groups_list) / sizeof(aic_gpio_groups_list[0]);

View File

@@ -67,6 +67,11 @@ void *aic_get_boot_resource(void)
return (void *)(boot_params_stash.r.a[1]);
}
void aic_set_boot_resource(void *res_addr)
{
boot_params_stash.r.a[1] = (u32)(uintptr_t)res_addr;
}
int aic_get_boot_image_id(void)
{
return get_boot_image_id(boot_params_stash.r.a[0]);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,6 +20,9 @@ enum {
GPIO_GROUP_MAX,
};
extern const int aic_gpio_groups_list[];
extern const int aic_gpio_group_size;
#define PA_BASE 0
#define PB_BASE 32
#define PC_BASE 64
@@ -34,7 +37,7 @@ enum {
#define PL_BASE 352
#define PM_BASE 384
#define PN_BASE 416
#define PO_BASE 448
#define PU_BASE 448
#define GPIOA(n) (PA_BASE + (n))
#define GPIOB(n) (PB_BASE + (n))
#define GPIOC(n) (PC_BASE + (n))
@@ -49,7 +52,7 @@ enum {
#define GPIOL(n) (PL_BASE + (n))
#define GPIOM(n) (PM_BASE + (n))
#define GPION(n) (PN_BASE + (n))
#define GPIOO(n) (PO_BASE + (n))
#define GPIOU(n) (PO_BASE + (n))
typedef enum {
PA0 = GPIOA(0),

View File

@@ -85,6 +85,7 @@ enum boot_controller aic_get_boot_controller(void);
int aic_get_boot_image_id(void);
unsigned long aic_timer_get_us(void);
void *aic_get_boot_resource(void);
void aic_set_boot_resource(void *res_addr);
void *aic_get_boot_resource_from_nand(void *dev, unsigned long pagesize,
nand_read fn);
void *aic_get_boot_args(void);

View File

@@ -186,6 +186,10 @@ save_boot_params_ret:
bltu a0, a1, 1b
2:
/* Reloc private params */
la a5, reloc_private_params
jalr a5
#ifndef __NO_SYSTEM_INIT
la a5, SystemInit
jalr a5

View File

@@ -36,6 +36,16 @@ config CPU_BASE
default 0xE0000000 if QEMU_RUN
depends on AIC_CHIP_D13X
config CPU_PSRAM_BASE
hex
default 0x40000000
depends on AIC_CHIP_D13X
config CPU_SRAM_BASE
hex
default 0x30040000
depends on AIC_CHIP_D13X
#--------------------------------------------
# interrupt global option
#--------------------------------------------

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2022-2024, ArtInChip, Artinchip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_gpio_id.h>
const int aic_gpio_groups_list[] = {
PA_GROUP,
PB_GROUP,
PC_GROUP,
PD_GROUP,
PE_GROUP,
PU_GROUP,
};
const int aic_gpio_group_size = sizeof(aic_gpio_groups_list) / sizeof(aic_gpio_groups_list[0]);

View File

@@ -67,6 +67,11 @@ void *aic_get_boot_resource(void)
return (void *)(boot_params_stash.r.a[1]);
}
void aic_set_boot_resource(void *res_addr)
{
boot_params_stash.r.a[1] = (u32)(uintptr_t)res_addr;
}
int aic_get_boot_image_id(void)
{
return get_boot_image_id(boot_params_stash.r.a[0]);

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -85,6 +85,7 @@ enum boot_controller aic_get_boot_controller(void);
int aic_get_boot_image_id(void);
unsigned long aic_timer_get_us(void);
void *aic_get_boot_resource(void);
void aic_set_boot_resource(void *res_addr);
void *aic_get_boot_resource_from_nand(void *dev, unsigned long pagesize,
nand_read fn);
void *aic_get_boot_args(void);

View File

@@ -223,6 +223,10 @@ e907_tcm_init:
bltu a0, a1, 1b
2:
/* Reloc private params */
la a5, reloc_private_params
jalr a5
#ifndef __NO_SYSTEM_INIT
la a5, SystemInit
jalr a5

View File

@@ -32,6 +32,16 @@ config CPU_BASE
default 0x4000000000 if QEMU_RUN
depends on AIC_CHIP_D21X
config CPU_DRAM_BASE
hex
default 0x40000000
depends on AIC_CHIP_D21X
config CPU_SRAM_BASE
hex
default 0x00100000
depends on AIC_CHIP_D21X
#--------------------------------------------
# cmu driver global option
#--------------------------------------------

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_gpio_id.h>
const int aic_gpio_groups_list[] = {
PA_GROUP,
PB_GROUP,
PC_GROUP,
PD_GROUP,
PE_GROUP,
PF_GROUP,
PG_GROUP,
PU_GROUP,
};
const int aic_gpio_group_size = sizeof(aic_gpio_groups_list) / sizeof(aic_gpio_groups_list[0]);

View File

@@ -67,6 +67,11 @@ void *aic_get_boot_resource(void)
return (void *)(boot_params_stash.r.a[1]);
}
void aic_set_boot_resource(void *res_addr)
{
boot_params_stash.r.a[1] = (u32)(uintptr_t)res_addr;
}
int aic_get_boot_image_id(void)
{
return get_boot_image_id(boot_params_stash.r.a[0]);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,10 +19,13 @@ enum {
PE_GROUP,
PF_GROUP,
PG_GROUP,
PO_GROUP = 14,
PU_GROUP = 14,
GPIO_GROUP_MAX,
};
extern const int aic_gpio_groups_list[];
extern const int aic_gpio_group_size;
#define PA_BASE 0
#define PB_BASE 32
#define PC_BASE 64
@@ -37,7 +40,7 @@ enum {
#define PL_BASE 352
#define PM_BASE 384
#define PN_BASE 416
#define PO_BASE 448
#define PU_BASE 448
#define GPIOA(n) (PA_BASE + (n))
#define GPIOB(n) (PB_BASE + (n))
#define GPIOC(n) (PC_BASE + (n))
@@ -52,7 +55,7 @@ enum {
#define GPIOL(n) (PL_BASE + (n))
#define GPIOM(n) (PM_BASE + (n))
#define GPION(n) (PN_BASE + (n))
#define GPIOO(n) (PO_BASE + (n))
#define GPIOU(n) (PU_BASE + (n))
typedef enum {
PA0 = GPIOA(0),

View File

@@ -85,6 +85,7 @@ enum boot_controller aic_get_boot_controller(void);
int aic_get_boot_image_id(void);
unsigned long aic_timer_get_us(void);
void *aic_get_boot_resource(void);
void aic_set_boot_resource(void *res_addr);
void *aic_get_boot_resource_from_nand(void *dev, unsigned long pagesize,
nand_read fn);
void *aic_get_boot_args(void);

View File

@@ -95,6 +95,10 @@ save_boot_params_ret:
bltu a0, a1, 1b
2:
/* Reloc private params */
la a5, reloc_private_params
jalr a5
#ifndef __NO_SYSTEM_INIT
la a5, SystemInit
jalr a5

View File

@@ -36,6 +36,16 @@ config CPU_BASE
default 0xE0000000 if QEMU_RUN
depends on AIC_CHIP_G73X
config CPU_PSRAM_BASE
hex
default 0x40000000
depends on AIC_CHIP_G73X
config CPU_SRAM_BASE
hex
default 0x30040000
depends on AIC_CHIP_G73X
#--------------------------------------------
# interrupt global option
#--------------------------------------------

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_gpio_id.h>
const int aic_gpio_groups_list[] = {
PA_GROUP,
PB_GROUP,
PC_GROUP,
PD_GROUP,
PE_GROUP,
PF_GROUP,
PG_GROUP,
PU_GROUP,
};
const int aic_gpio_group_size = sizeof(aic_gpio_groups_list) / sizeof(aic_gpio_groups_list[0]);

View File

@@ -67,6 +67,11 @@ void *aic_get_boot_resource(void)
return (void *)(boot_params_stash.r.a[1]);
}
void aic_set_boot_resource(void *res_addr)
{
boot_params_stash.r.a[1] = (u32)(uintptr_t)res_addr;
}
int aic_get_boot_image_id(void)
{
return get_boot_image_id(boot_params_stash.r.a[0]);

Binary file not shown.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,10 +19,13 @@ enum {
PE_GROUP,
PF_GROUP,
PG_GROUP,
PO_GROUP = 14,
PU_GROUP = 14,
GPIO_GROUP_MAX,
};
extern const int aic_gpio_groups_list[];
extern const int aic_gpio_group_size;
#define PA_BASE 0
#define PB_BASE 32
#define PC_BASE 64
@@ -37,7 +40,7 @@ enum {
#define PL_BASE 352
#define PM_BASE 384
#define PN_BASE 416
#define PO_BASE 448
#define PU_BASE 448
#define GPIOA(n) (PA_BASE + (n))
#define GPIOB(n) (PB_BASE + (n))
#define GPIOC(n) (PC_BASE + (n))
@@ -52,7 +55,7 @@ enum {
#define GPIOL(n) (PL_BASE + (n))
#define GPIOM(n) (PM_BASE + (n))
#define GPION(n) (PN_BASE + (n))
#define GPIOO(n) (PO_BASE + (n))
#define GPIOU(n) (PU_BASE + (n))
typedef enum {
PA0 = GPIOA(0),

View File

@@ -85,6 +85,7 @@ enum boot_controller aic_get_boot_controller(void);
int aic_get_boot_image_id(void);
unsigned long aic_timer_get_us(void);
void *aic_get_boot_resource(void);
void aic_set_boot_resource(void *res_addr);
void *aic_get_boot_resource_from_nand(void *dev, unsigned long pagesize,
nand_read fn);
void *aic_get_boot_args(void);

View File

@@ -1,3 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2022-2024, ArtInChip Technology Co., Ltd
import os
import platform
@@ -33,9 +37,23 @@ BUILD = 'release'
if BUILD == 'debug':
CFLAGS_DBG = ' -O0 -gdwarf-2 '
AFLAGS_DBG = ' -gdwarf-2 '
B_AFLAGS = ''
B_CFLAGS = ''
LFLAGS = ''
B_AFLAGS += ' -D_ENABLE_BACK_TRACE_STACK_ '
CFLAGS_DBG += ' -fno-omit-frame-pointer '
B_AFLAGS += ' -D_NO_OMIT_FRAME_POINT_ '
#B_CFLAGS += ' -fstack-protector-all '
#LFLAGS += ' -Wl,--wrap=__stack_chk_fail '
else:
CFLAGS_DBG = ' -O2 -g2'
AFLAGS_DBG = ''
B_AFLAGS = ''
B_CFLAGS = ''
LFLAGS = ''
B_AFLAGS += ' -D_ENABLE_BACK_TRACE_STACK_ '
#CFLAGS_DBG += ' -fno-omit-frame-pointer '
#B_AFLAGS += ' -D_NO_OMIT_FRAME_POINT_ '
prj_out_dir = ''
if os.environ.get('PRJ_OUT_DIR'):
@@ -73,8 +91,8 @@ if PLATFORM == 'gcc':
if CPUNAME == 'e906' or CPUNAME == 'e907':
DEVICE = ' -march=rv32imac_xtheade -mabi=ilp32'
B_CFLAGS = ' -c -g -ffunction-sections -fdata-sections -Wall -mcmodel=medlow'
B_AFLAGS = ' -c' + ' -x assembler-with-cpp' + ' -D__ASSEMBLY__'
B_CFLAGS += ' -c -g -ffunction-sections -fdata-sections -Wall -mcmodel=medany '
B_AFLAGS += ' -c' + ' -x assembler-with-cpp' + ' -D__ASSEMBLY__'
CFLAGS = DEVICE + B_CFLAGS + CFLAGS_DBG
AFLAGS = DEVICE + B_AFLAGS + AFLAGS_DBG
CXXFLAGS = CFLAGS

View File

@@ -223,6 +223,10 @@ e907_tcm_init:
bltu a0, a1, 1b
2:
/* Reloc private params */
la a5, reloc_private_params
jalr a5
#ifndef __NO_SYSTEM_INIT
la a5, SystemInit
jalr a5

View File

@@ -8,6 +8,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <rtconfig.h>
#ifdef KERNEL_RTTHREAD
#include <rtthread.h>
#endif
#include <csi_core.h>
void (*trap_c_callback)(void);
@@ -37,12 +42,106 @@ void trap_c(uint32_t *regs)
printf("mtval : %08lx\n", __get_MTVAL());
printf("mepc : %08lx\n", regs[31]);
printf("mstatus: %08lx\n", regs[32]);
printf("\n");
if (trap_c_callback)
{
if (trap_c_callback) {
trap_c_callback();
}
while (1);
//while (1);
}
#ifdef KERNEL_RTTHREAD
#define CMB_CALL_STACK_MAX_DEPTH 32
extern size_t __stext;
extern size_t __etext;
extern rt_ubase_t g_base_irqstack;
extern rt_ubase_t g_top_irqstack;
void print_stack(uint32_t *stack_point,uint32_t*stack_point1,uint32_t epc)
{
int i = 0;
uint32_t sp = (uint32_t)stack_point;
uint32_t pc;
uint32_t base_irqstack = (uint32_t)&g_base_irqstack;
uint32_t top_irqstack = (uint32_t)&g_top_irqstack;
uint32_t stack_addr = (uint32_t) rt_thread_self()->stack_addr;
uint32_t stack_size = rt_thread_self()->stack_size;
printf("__stext:%p __etext:%p,stack:\n", &__stext, &__etext);
if (sp >= base_irqstack && sp <= top_irqstack) {
//printf("[%s:%d]base_irqstack::0x%08lx top_irqstack::0x%08lx\n",__FUNCTION__,__LINE__, base_irqstack, top_irqstack);
printf("base_irqstack::0x%08lx top_irqstack::0x%08lx\n", base_irqstack, top_irqstack);
for (; sp < top_irqstack; sp += sizeof(uint32_t)) {
pc = *((uint32_t *)sp);
printf("0x%08lx ", pc);
if ((i % 4) == 3) {
printf("\n");
}
i++;
}
sp = (uint32_t)stack_point1;
printf("\n");
}
//printf("[%s:%d]stack_addr:0x%08lx stack_addr_end:0x%08lx\n",__FUNCTION__,__LINE__, stack_addr, stack_addr + stack_size);
printf("stack_addr:0x%08lx stack_addr_end:0x%08lx\n",stack_addr, stack_addr + stack_size);
for (i = 0; sp < stack_addr + stack_size; sp += sizeof(uint32_t)) {
pc = *((uint32_t *)sp);
printf("0x%08lx ", pc);
if ((i % 4) == 3) {
printf("\n");
}
i++;
}
printf("\n\n");
}
void print_back_trace(int32_t n,rt_ubase_t *regs)
{
int i = 0;
printf("back_trace:\n");
for(i = 0; i < n; i++) {
printf("0x%08lx\n", regs[i]);
}
}
void backtrace_call_stack(rt_ubase_t *stack_point,rt_ubase_t*stack_point1,rt_ubase_t epc)
{
int depth = 0;
rt_ubase_t sp = (rt_ubase_t)stack_point;
rt_ubase_t pc;
size_t code_start_addr = (size_t)&__stext;
size_t code_end_addr = (size_t)&__etext;
rt_ubase_t base_irqstack = (rt_ubase_t)&g_base_irqstack;
rt_ubase_t top_irqstack = (rt_ubase_t)&g_top_irqstack;
rt_ubase_t stack_addr = (rt_ubase_t) rt_thread_self()->stack_addr;
rt_ubase_t stack_size = rt_thread_self()->stack_size;
printf("[%s:%d]__stext:%p __etext:%p\r\n",__FUNCTION__,__LINE__, &__stext, &__etext);
printf("%08lx\n", epc);
if (sp >= base_irqstack && sp <= top_irqstack) {
for (; sp < top_irqstack; sp += sizeof(rt_ubase_t)) {
pc = *((rt_ubase_t *)sp);
if((pc >= code_start_addr) && (pc <= code_end_addr) && (depth < CMB_CALL_STACK_MAX_DEPTH)) {
printf("%08lx\n", pc);
depth++;
}
}
sp = (rt_ubase_t)stack_point1;
}
depth = 0;
for (; sp < stack_addr + stack_size; sp += sizeof(rt_ubase_t)) {
pc = *((rt_ubase_t *)sp);
if((pc >= code_start_addr) && (pc <= code_end_addr) && (depth < CMB_CALL_STACK_MAX_DEPTH)) {
printf("%08lx\n", pc);
depth++;
}
}
}
#endif

View File

@@ -51,6 +51,14 @@ Default_IRQHandler:
.long 0x0040000b
#endif
#if defined(_ENABLE_BACK_TRACE_STACK_) && defined(_NO_OMIT_FRAME_POINT_)
addi sp,sp,-8
STORE s0,(sp)
csrr a0, mepc
STORE a0, 4(sp)
addi s0, sp, 8
#endif
#ifdef ARCH_RISCV_FPU
addi sp, sp, -(20 * FREGBYTES)
@@ -138,6 +146,12 @@ Default_IRQHandler:
addi sp, sp, (20 * FREGBYTES)
#endif
#if defined(_ENABLE_BACK_TRACE_STACK_) && defined(_NO_OMIT_FRAME_POINT_)
lw s0, (sp)
addi sp, sp, 8
#endif
#ifdef __riscv_xthead
ipop
#else
@@ -159,8 +173,8 @@ trap:
csrr t0, mcause
blt t0, x0, .Lirq
addi sp, sp, 4
la t0, g_trap_sp
//la t0, g_trap_sp
mv t0, sp
addi t0, t0, -132
sw x1, 0(t0)
@@ -207,6 +221,96 @@ trap:
la a5, trap_c
jalr a5
#ifdef KERNEL_RTTHREAD
mv a0, sp
addi a0, a0, 132
csrr a1, mscratch
csrr a2, mepc
la a5, print_stack
jalr a5
#endif
#if defined(_ENABLE_BACK_TRACE_STACK_) && defined(KERNEL_RTTHREAD)
#define CALL_STACK_MAX_DEPTH 32
la a0, rt_current_thread
beqz a0, .
#ifdef _NO_OMIT_FRAME_POINT_
mv t0, sp
la t1, CALL_STACK_MAX_DEPTH
slli t1, t1, 2
sub t0, t0, t1
csrr a1, mepc
STORE a1, (t0)
mv a1, s0
li t1, 1
1:
// check sram addr
li t2, 0x30000000
la t3, AIC_SRAM_TOTAL_SIZE
add t3, t2, t3
blt a1, t2, 2f
bge a1, t3, 2f
addi a2, a1, -(4)
blt a2, t2, 2f
bge a2, t3, 2f
addi a2, a1, -(8)
blt a2, t2, 2f
bge a2, t3, 2f
j 3f
2:
// check psram addr
li t2, 0x40000000
la t3, AIC_PSRAM_SIZE
add t3, t2, t3
blt a1, t2, 4f
bge a1, t3, 4f
addi a2, a1, -(4)
blt a2, t2, 4f
bge a2, t3, 4f
addi a2, a1, -(8)
blt a2, t2, 4f
bge a2, t3, 4f
3:
// get ra
LOAD a2, -4(a1)
slli t2, t1, 2
add t2, t2, t0
STORE a2, (t2)
// get next fp
LOAD a1, -8(a1)
//inc call depth
addi t1, t1, 1
// check end
li a2, 0xdeadbeef
beq a1, a2, 4f
la a2, CALL_STACK_MAX_DEPTH
blt t1, a2, 1b
4:
mv a0, t1
mv a1, t0
mv sp, t0
la a5, print_back_trace
jalr a5
#else
mv a0, sp
addi a0, a0, 132
csrr a1, mscratch
csrr a2, mepc
la a5, backtrace_call_stack
jalr a5
#endif
#endif
j .
.Lirq:
lw t0, 0x0(sp)

View File

@@ -19,7 +19,7 @@ extern "C" {
/* Luban-Lite version information */
#define LL_VERSION 1 /**< major version number */
#define LL_SUBVERSION 1 /**< minor version number */
#define LL_REVISION 0 /**< revise version number */
#define LL_REVISION 1 /**< revise version number */
typedef __signed__ char s8;
typedef unsigned char u8;
@@ -384,6 +384,9 @@ typedef enum {
#endif
#ifdef AIC_DRAM_CMA_EN
MEM_DRAM_CMA,
#endif
#ifdef AIC_BOOTLOADER
MEM_RESERVED,
#endif
MAX_MEM_REGION,
} aic_mem_region_t;

View File

@@ -1,12 +1,37 @@
/*
* Copyright (c) 2020-2021 Artinchip Technology Co., Ltd
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Wu Dehuang <dehuang.wu@artinchip.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aic_common.h>
#include <boot_param.h>
#include <private_param.h>
char private_params_stash[1024];
void reloc_private_params(void)
{
void *res_addr;
int i;
res_addr = aic_get_boot_resource();
if (res_addr) {
for (i = 0; i < sizeof(private_params_stash); i += 4) {
memcpy(&private_params_stash[i], res_addr, 4);
if (*(u32 *)res_addr == DATA_SECT_TYPE_END)
break;
res_addr += 4;
}
aic_set_boot_resource(private_params_stash);
}
}
static u32 *find_section(void *start, u32 type)
{
u32 *p = start, data_type, data_len;

View File

@@ -21,45 +21,31 @@
#include <of.h>
#endif
extern const int aic_gpio_groups_list[];
int list_pinmux(int argc, char *argv[])
{
unsigned int group, pin, func, i;
unsigned int group, pin, func, i, j;
pin_name_t pin_name, pin_name_max;
for (i = 0; i < GPIO_GROUP_MAX; i++)
{
switch (i)
{
case PA_GROUP:
case PB_GROUP:
case PC_GROUP:
case PD_GROUP:
case PE_GROUP:
#ifndef AIC_CHIP_D12X
case PF_GROUP:
case PG_GROUP:
case PO_GROUP:
#endif
for (i = 0, j = 0; i < GPIO_GROUP_MAX && j < aic_gpio_group_size; i++) {
if (i == aic_gpio_groups_list[j]) {
pin_name = PA_BASE + i * GPIO_GROUP_SIZE;
pin_name_max = pin_name + GPIO_GROUP_SIZE;
while (pin_name < pin_name_max)
{
while (pin_name < pin_name_max) {
group = GPIO_GROUP(pin_name);
pin = GPIO_GROUP_PIN(pin_name);
func = 0;
hal_gpio_get_func(group, pin, &func);
if (func)
{
printf("P%c%d: function: %d\n", group + 'A', pin, func);
}
printf("P%c%u: function: %u\n", group + 'A', pin, func);
pin_name++;
}
break;
default:
break;
j++;
}
}

Some files were not shown because too many files have changed in this diff Show More