Skip to content

Commit 8af201e

Browse files
committed
bsp: k230: add pdma driver
pdma = Peripheral DMA Signed-off-by: Wang Chen <[email protected]>
1 parent 9dbdf6e commit 8af201e

File tree

3 files changed

+475
-0
lines changed

3 files changed

+475
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# RT-Thread building script for component
2+
3+
from building import *
4+
5+
cwd = GetCurrentDir()
6+
src = Glob('*.c') + Glob('*.S')
7+
CPPPATH = [cwd]
8+
9+
group = DefineGroup('PDMA', src, depend = ['RT_USING_PDMA'], CPPPATH = CPPPATH)
10+
11+
objs = [group]
12+
13+
list = os.listdir(cwd)
14+
15+
for item in list:
16+
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
17+
objs = objs + SConscript(os.path.join(item, 'SConscript'))
18+
19+
Return('objs')
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
2+
*
3+
* Redistribution and use in source and binary forms, with or without
4+
* modification, are permitted provided that the following conditions are met:
5+
* 1. Redistributions of source code must retain the above copyright
6+
* notice, this list of conditions and the following disclaimer.
7+
* 2. Redistributions in binary form must reproduce the above copyright
8+
* notice, this list of conditions and the following disclaimer in the
9+
* documentation and/or other materials provided with the distribution.
10+
*
11+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
12+
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
13+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#include <rtdbg.h>
27+
#include "drv_pdma.h"
28+
#include <stdbool.h>
29+
#include <stdlib.h>
30+
#include <cache.h>
31+
#include <rtthread.h>
32+
#include <rthw.h>
33+
#include "drivers/dev_pin.h"
34+
#include <rtdevice.h>
35+
#include <riscv_io.h>
36+
#include <rtdef.h>
37+
#include "ioremap.h"
38+
#include "board.h"
39+
#include <stdio.h>
40+
#include <page.h>
41+
#include <mmu.h>
42+
#include "drv_hardlock.h"
43+
44+
static int pdma_hardlock;
45+
static pdma_reg_t *pdma_reg;
46+
47+
static size_t g_pdma_page_size[8];
48+
static bool g_pdma_alloc_page[8];
49+
/***************************************************************
50+
* general cfg
51+
***************************************************************/
52+
static void pdma_ch_enable(rt_uint8_t ch)
53+
{
54+
while(0 != kd_hardlock_lock(pdma_hardlock));
55+
pdma_reg->pdma_ch_en |= (1 << ch);
56+
kd_hardlock_unlock(pdma_hardlock);
57+
}
58+
59+
static void pdma_ch_disable(rt_uint8_t ch)
60+
{
61+
while(0 != kd_hardlock_lock(pdma_hardlock));
62+
pdma_reg->pdma_ch_en &= (~(1 << ch));
63+
kd_hardlock_unlock(pdma_hardlock);
64+
}
65+
66+
static int pdma_interrupt_en(rt_uint8_t ch, rt_uint32_t mask)
67+
{
68+
if (ch >= PDMA_CH_MAX)
69+
return -1;
70+
71+
while(0 != kd_hardlock_lock(pdma_hardlock));
72+
pdma_reg->dma_int_mask &= (~(mask << ch));
73+
kd_hardlock_unlock(pdma_hardlock);
74+
75+
return 0;
76+
}
77+
78+
static int pdma_interrupt_mask(rt_uint8_t ch, rt_uint32_t mask)
79+
{
80+
if (ch >= PDMA_CH_MAX)
81+
return -1;
82+
83+
while(0 != kd_hardlock_lock(pdma_hardlock));
84+
pdma_reg->dma_int_mask |= (mask << ch);
85+
kd_hardlock_unlock(pdma_hardlock);
86+
87+
return 0;
88+
}
89+
90+
rt_uint32_t k_pdma_interrupt_stat()
91+
{
92+
return pdma_reg->dma_int_stat;
93+
}
94+
95+
void k_pdma_int_clear_all(rt_uint32_t clear)
96+
{
97+
int ch = 0;
98+
rt_uint32_t reg;
99+
100+
reg = pdma_reg->dma_int_stat;
101+
pdma_reg->dma_int_stat = clear;
102+
103+
/* free llt */
104+
if (reg & 0xff) {
105+
for (ch = 0; ch < 8; ch++) {
106+
if ((reg >> ch) & 0x1) {
107+
k_pdma_llt_free(ch);
108+
}
109+
}
110+
}
111+
}
112+
113+
int k_pdma_int_clear(rt_uint8_t ch, rt_uint32_t clear)
114+
{
115+
if (ch >= PDMA_CH_MAX)
116+
return -1;
117+
118+
pdma_reg->dma_int_stat = (clear << ch);
119+
120+
if (clear == PDONE_INT) {
121+
k_pdma_llt_free(ch);
122+
}
123+
124+
return 0;
125+
}
126+
127+
void k_pdma_start(rt_uint8_t ch)
128+
{
129+
pdma_reg->pdma_ch_reg[ch].ch_ctl = 0x1;
130+
}
131+
132+
void k_pdma_stop(rt_uint8_t ch)
133+
{
134+
pdma_reg->pdma_ch_reg[ch].ch_ctl = 0x2;
135+
}
136+
137+
void k_pdma_resume(rt_uint8_t ch)
138+
{
139+
pdma_reg->pdma_ch_reg[ch].ch_ctl = 0x4;
140+
}
141+
142+
bool jamlnik_pdma_is_busy(rt_uint8_t ch)
143+
{
144+
if (pdma_reg->pdma_ch_reg[ch].ch_status & 0x1)
145+
return true;
146+
else
147+
return false;
148+
}
149+
150+
bool k_pdma_is_pause(rt_uint8_t ch)
151+
{
152+
if (pdma_reg->pdma_ch_reg[ch].ch_status & 0x2)
153+
return true;
154+
else
155+
return false;
156+
}
157+
158+
static rt_uint32_t *pdma_llt_cal(usr_pdma_cfg_t pdma_cfg)
159+
{
160+
int i;
161+
rt_uint32_t list_num;
162+
pdma_llt_t *llt_list;
163+
164+
list_num = (pdma_cfg.line_size - 1) / PDMA_MAX_LINE_SIZE + 1;
165+
166+
g_pdma_page_size[pdma_cfg.ch] = rt_page_bits(sizeof(pdma_llt_t) * list_num);
167+
g_pdma_alloc_page[pdma_cfg.ch] = true;
168+
llt_list = (pdma_llt_t *)rt_pages_alloc(g_pdma_page_size[pdma_cfg.ch]);
169+
170+
for (i = 0; i < list_num; i++) {
171+
llt_list[i].src_addr = ((rt_uint32_t)(intptr_t)pdma_cfg.src_addr + PDMA_MAX_LINE_SIZE*i);
172+
llt_list[i].dst_addr = ((rt_uint32_t)(intptr_t)pdma_cfg.dst_addr + PDMA_MAX_LINE_SIZE*i);
173+
174+
if (i == list_num -1) {
175+
llt_list[i].line_size = pdma_cfg.line_size % PDMA_MAX_LINE_SIZE;
176+
llt_list[i].next_llt_addr = 0;
177+
} else {
178+
llt_list[i].line_size = PDMA_MAX_LINE_SIZE;
179+
llt_list[i].next_llt_addr = (rt_uint32_t)(intptr_t)(&llt_list[i+1]);
180+
}
181+
182+
llt_list[i].pause = 0;
183+
}
184+
185+
186+
rt_hw_cpu_dcache_clean_invalidate_local((uint64_t*)llt_list, sizeof(pdma_llt_t)*list_num);
187+
188+
// return (rt_uint32_t *)llt_list;
189+
return (void *)((char *)llt_list + PV_OFFSET);
190+
}
191+
192+
int k_pdma_config(usr_pdma_cfg_t pdma_cfg)
193+
{
194+
rt_uint8_t ch = pdma_cfg.ch;
195+
196+
if (ch >= PDMA_CH_MAX)
197+
return -1;
198+
199+
k_pdma_stop(ch);
200+
while (pdma_reg->pdma_ch_reg[ch].ch_status & 0x1)
201+
;
202+
pdma_ch_enable(ch);
203+
k_pdma_int_clear(ch, PDONE_INT | PITEM_INT | PPAUSE_INT | PTOUT_INT);
204+
205+
pdma_reg->pdma_ch_reg[ch].ch_cfg = pdma_cfg.pdma_ch_cfg;
206+
pdma_reg->ch_peri_dev_sel[ch] = pdma_cfg.device;
207+
pdma_reg->pdma_ch_reg[ch].ch_llt_saddr = (rt_uint32_t)(intptr_t)pdma_llt_cal(pdma_cfg);
208+
209+
return 0;
210+
}
211+
212+
void k_pdma_llt_free(rt_uint8_t ch)
213+
{
214+
rt_uint32_t *llt_list;
215+
llt_list = (rt_uint32_t *)(intptr_t)pdma_reg->pdma_ch_reg[ch].ch_llt_saddr;
216+
if (g_pdma_alloc_page[ch])
217+
{
218+
rt_pages_free(llt_list, g_pdma_page_size[ch]);
219+
g_pdma_alloc_page[ch] = false;
220+
//rt_free(llt_list);
221+
}
222+
}
223+
224+
int rt_hw_pdma_device_init(void)
225+
{
226+
rt_err_t ret = RT_EOK;
227+
228+
pdma_reg = rt_ioremap((void *)PDMA_BASE_ADDR, PDMA_IO_SIZE);
229+
230+
if(RT_NULL == pdma_reg) {
231+
rt_kprintf("pdma module ioremap error!\n");
232+
return -RT_ERROR;
233+
}
234+
235+
if(kd_request_lock(HARDLOCK_PDMA)) {
236+
rt_kprintf("Fail to request hardlock-%d\n", HARDLOCK_PDMA);
237+
pdma_hardlock = -1;
238+
} else
239+
pdma_hardlock = HARDLOCK_PDMA;
240+
241+
return ret;
242+
}
243+
INIT_BOARD_EXPORT(rt_hw_pdma_device_init);
244+
245+
246+
247+
248+
249+
250+
251+
252+
253+
254+
255+

0 commit comments

Comments
 (0)