231 lines
5.9 KiB
C
231 lines
5.9 KiB
C
![]() |
// +FHDR------------------------------------------------------------
|
||
|
// Copyright (c) 2022 SmartLogic.
|
||
|
// ALL RIGHTS RESERVED
|
||
|
// -----------------------------------------------------------------
|
||
|
// Filename : arm_csu.c
|
||
|
// Author : xinxin.li
|
||
|
// Created On : 2022-11-23
|
||
|
// Last Modified :
|
||
|
// -----------------------------------------------------------------
|
||
|
// Description:
|
||
|
//
|
||
|
//
|
||
|
// -FHDR------------------------------------------------------------
|
||
|
#include "ucp_csu.h"
|
||
|
#include "arm_csu.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <stddef.h>
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <ucontext.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/mman.h>
|
||
|
#include <fcntl.h>
|
||
|
#include "ucp_utility.h"
|
||
|
#include "ucp_printf.h"
|
||
|
#include "drv_init.h"
|
||
|
|
||
|
|
||
|
uint8_t* virMemAddr = NULL;
|
||
|
int arm_csu_init()
|
||
|
{
|
||
|
if (-1 == g_drv_mem_fd)
|
||
|
{
|
||
|
// printf("open dev mem. \r\n");
|
||
|
g_drv_mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
|
||
|
if (0 > g_drv_mem_fd)
|
||
|
{
|
||
|
UCP_PRINT_ERROR("open /dev/mem error\n");
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// printf("start mmap. \r\n");
|
||
|
virMemAddr = (uint8_t*)mmap(NULL, CSU_DEV_MAP_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, g_drv_mem_fd, AP_CSU_BASE);
|
||
|
if ((uint8_t*)(-1) == virMemAddr)
|
||
|
{
|
||
|
UCP_PRINT_ERROR("mmap error!!");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// printf("csu init. \r\n");
|
||
|
int i;
|
||
|
for (i = 0; i < 16; i++)
|
||
|
{
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_DMAYNUMXNUM0) + (i<<3)) = ((4<<16)|1024);
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_DMAYSTEPL0) + (i<<3)) = 1024;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_DMAYSTEPH0) + (i<<3)) = 0;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_DMAZSTEPL0) + (i<<3)) = 4096;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_DMAZSTEPH0) + (i<<3)) = 0;
|
||
|
}
|
||
|
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_EM_BS_SMSEL_PREDATANUM)) = (0x2A<<16) | (0x0<<14) | (0x5<<5) | 0x9; // (0x3F<<16);
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_EM_BS_SMSEL_PREDATANUM)) = (0x2A<<16) | (0x1<<14) | (0x5<<5) | 0x9;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_EM_BS_SMSEL_PREDATANUM)) = (0x2A<<16) | (0x2<<14) | (0x5<<5) | 0x9;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_EM_BS_SMSEL_PREDATANUM)) = (0x2A<<16) | (0x3<<14) | (0x5<<5) | 0x9;
|
||
|
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_FINDDMATAG)) = 0x60;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_TAGMASK0)) = 0xFFFFFFFF;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_TAGMASK1)) = 0xFFFFFFFF;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_TAGMASK2)) = 0xFFFFFFFF;
|
||
|
*((volatile uint32_t*)(virMemAddr+AP_CSU_TAGMASK3)) = 0xFFFFFFFF;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int get_arm_csu_status(uint8_t tag)
|
||
|
{
|
||
|
if (31 < tag)
|
||
|
{
|
||
|
UCP_PRINT_ERROR("input para error! tag = %d. \r\n", tag);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
uint32_t status = VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS);
|
||
|
return (status&(1<<tag)); // 0: not finished, 1: finished
|
||
|
}
|
||
|
|
||
|
int arm_csu_wait_done(uint8_t tag)
|
||
|
{
|
||
|
if (31 < tag)
|
||
|
{
|
||
|
UCP_PRINT_ERROR("input para error! tag = %d. \r\n", tag);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
volatile uint32_t status = 0;
|
||
|
while (1)
|
||
|
{
|
||
|
status = VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS);
|
||
|
// printf("tag = %d, dmastatus = 0x%x. \r\n", tag, status);
|
||
|
if (0 != (status&(1<<tag)))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// while (0 == (VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS) & (1<<tag)));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int arm_csu_wait_all_done(void)
|
||
|
{
|
||
|
#if 0
|
||
|
for (int i = 0; i < 32; i++)
|
||
|
{
|
||
|
arm_csu_wait_done(i);
|
||
|
}
|
||
|
#endif
|
||
|
while (1)
|
||
|
{
|
||
|
int cmdNum = 0;
|
||
|
for (int i = 0; i < 4; i++)
|
||
|
{
|
||
|
cmdNum += VIR_ADDR_VAL(virMemAddr, AP_CSU_CMDFIFO0_NUM+(i<<2));
|
||
|
}
|
||
|
if (0 == cmdNum)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//CmdFIFO 0 1 2 3
|
||
|
//tag 0 1 2 3 reg_group = 0(0->1)
|
||
|
//tag 4 5 6 7 1(2->3)
|
||
|
//tag 8 9 10 11 2(4->5)
|
||
|
//tag 12 13 14 15 3(6->7)
|
||
|
//tag 16 17 18 19 4(8->9)
|
||
|
//tag 20 21 22 23 5(10->11)
|
||
|
//tag 24 25 26 27 6(12->13)
|
||
|
//tag 28 29 30 31 7(14->15)
|
||
|
|
||
|
// get unused register group according to tag number
|
||
|
int get_free_reg_group(uint8_t tag)
|
||
|
{
|
||
|
if (31 < tag)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
uint32_t dmaStatus = VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS);
|
||
|
uint8_t fifoNum = tag % 4;
|
||
|
uint8_t regGroup = tag / 4;
|
||
|
if (0 == (dmaStatus & (0xF<<regGroup)))
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return ((fifoNum<<16) | regGroup); // [31:16]fifoNum(0~3), [15:0]reg group(0~7)
|
||
|
}
|
||
|
|
||
|
int get_free_channel()
|
||
|
{
|
||
|
while (1)
|
||
|
{
|
||
|
for (int tag = 0; tag < 32; tag++)
|
||
|
{
|
||
|
if (0 == (VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS) & (1<<tag)))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
uint32_t temp = get_free_reg_group(tag);
|
||
|
if (-1 == temp)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
uint8_t regGroup = temp & 0xFF;
|
||
|
uint8_t fifoNum = (temp>>16) & 0xFF;
|
||
|
int ret = regGroup | (fifoNum<<8) | (tag<<16);
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int arm_csu_dma_1D_transfer(uint64_t addrSrc, uint64_t addrDst, uint32_t dataLen)
|
||
|
{
|
||
|
uint8_t regGroup = 0;
|
||
|
uint8_t fifoNum = 0;
|
||
|
uint8_t tag = 0;
|
||
|
uint32_t temp = get_free_channel();
|
||
|
// printf("get free channle: 0x%x. \r\n", temp);
|
||
|
|
||
|
regGroup = temp & 0xFF;
|
||
|
fifoNum = (temp>>8) & 0xFF;
|
||
|
tag = (temp>>16)&0xFF;
|
||
|
|
||
|
uint8_t offset = regGroup << 6;
|
||
|
// src reg
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMAADDRL0 + offset) = addrSrc & 0xFFFFFFFF;
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMAADDRH0 + offset) = addrSrc >> 32;
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASIZEGRANALLNUM0 + offset) = (0xF<<28) | dataLen;
|
||
|
// dst reg
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMAADDRL1 + offset) = addrDst & 0xFFFFFFFF;
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMAADDRH1 + offset) = addrDst >> 32;
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASIZEGRANALLNUM1 + offset) = (0xE<<24) | dataLen; // write global, size=0
|
||
|
|
||
|
VIR_ADDR_VAL(virMemAddr, AP_CSU_CMDHIGHDATA) = 0;
|
||
|
stCsuDmaCmdL dmaCmdL;
|
||
|
dmaCmdL.dmaType = 1;
|
||
|
dmaCmdL.idSrc = 0 + (regGroup<<1);
|
||
|
dmaCmdL.idDst = 1 + (regGroup<<1);
|
||
|
dmaCmdL.dmaTag = tag;
|
||
|
//(uint32_t)(VIR_ADDR_VAL(virMemAddr, AP_CSU_CMDFIFO0+(fifoNum<<2))) = (uint32_t)(*((uint32_t*)(&dmaCmdL)));
|
||
|
memcpy((uint32_t*)(virMemAddr+AP_CSU_CMDFIFO0+(fifoNum<<2)), (uint32_t*)(&dmaCmdL), 4);
|
||
|
|
||
|
return tag;
|
||
|
}
|
||
|
|
||
|
|
||
|
|