242 lines
6.4 KiB
C
242 lines
6.4 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_fd0)
|
|
{
|
|
// printf("open dev mem. \r\n");
|
|
g_drv_mem_fd0 = open("/dev/mem", O_RDWR|O_SYNC);
|
|
if (0 > g_drv_mem_fd0)
|
|
{
|
|
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_fd0, 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)
|
|
|
|
//tag 0 8 16 24 reg_group = 0(0->1) CmdFIFO =0
|
|
//tag 1 9 17 25 1(2->3) 1
|
|
//tag 2 10 18 26 2(4->5) 2
|
|
//tag 3 11 19 27 3(6->7) 3
|
|
//tag 4 12 20 28 4(8->9) 0
|
|
//tag 5 13 21 29 5(10->11) 1
|
|
//tag 6 14 22 30 6(12->13) 2
|
|
//tag 7 15 23 31 7(14->15) 3
|
|
|
|
// get unused register group according to tag number
|
|
int get_free_reg_group(uint8_t tag)
|
|
{
|
|
if (31 < tag)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
uint8_t fifoNum = tag & 0x3; // tag % 4;
|
|
uint8_t regGroup = tag & 0x7; // tag / 4;
|
|
uint32_t bitMap = (0x01010101<<regGroup);
|
|
uint32_t dmaStatus = VIR_ADDR_VAL(virMemAddr, AP_CSU_DMASTATUS);
|
|
//if (0 == (dmaStatus & (0xF<<regGroup)))
|
|
if (bitMap != (dmaStatus & bitMap))
|
|
{
|
|
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;
|
|
|
|
uint16_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;
|
|
}
|
|
|
|
|
|
|