fh_dma.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618
  1. /*
  2. * This file is part of FH8620 BSP for RT-Thread distribution.
  3. *
  4. * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
  5. * All rights reserved
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Visit http://www.fullhan.com to get contact with Fullhan.
  22. *
  23. * Change Logs:
  24. * Date Author Notes
  25. */
  26. /*****************************************************************************
  27. * Include Section
  28. * add all #include here
  29. *****************************************************************************/
  30. //#include "drivers/fh_dma.h"
  31. #include "fh_dma.h"
  32. #include "mmu.h"
  33. #include "drivers/dma.h"
  34. #include <stdint.h>
  35. #include <rtdevice.h>
  36. #include <rthw.h>
  37. #include "fh_arch.h"
  38. #include "mmu.h"
  39. #include "fh_def.h"
  40. /*****************************************************************************
  41. * Define section
  42. * add all #define here
  43. *****************************************************************************/
  44. //#define DMA_DEBUG
  45. #ifdef DMA_DEBUG
  46. #define FH_DMA_DEBUG(fmt, args...) \
  47. rt_kprintf(fmt,##args);
  48. #else
  49. #define FH_DMA_DEBUG(fmt, args...)
  50. #endif
  51. #define DMA_REG_BASE (0xEE000000)
  52. #define DMA_CONTROLLER_NUMBER (1)
  53. #define WORK_QUEUE_STACK_SIZE 512
  54. #define WORK_QUEUE_PRIORITY 12
  55. #define TEST_PER_NO (10)
  56. #define DESC_MAX_SIZE (20)
  57. /*********************************
  58. *
  59. * copy from the linux core start
  60. *
  61. *********************************/
  62. //this is the ip reg offset....don't change!!!!!!!
  63. #define DW_DMA_MAX_NR_CHANNELS 8
  64. /*
  65. * Redefine this macro to handle differences between 32- and 64-bit
  66. * addressing, big vs. little endian, etc.
  67. */
  68. #define DW_REG(name) rt_uint32_t name; rt_uint32_t __pad_##name
  69. /* Hardware register definitions. */
  70. struct dw_dma_chan_regs {
  71. DW_REG(SAR); /* Source Address Register */
  72. DW_REG(DAR); /* Destination Address Register */
  73. DW_REG(LLP); /* Linked List Pointer */
  74. rt_uint32_t CTL_LO; /* Control Register Low */
  75. rt_uint32_t CTL_HI; /* Control Register High */
  76. DW_REG(SSTAT);
  77. DW_REG(DSTAT);
  78. DW_REG(SSTATAR);
  79. DW_REG(DSTATAR);
  80. rt_uint32_t CFG_LO; /* Configuration Register Low */
  81. rt_uint32_t CFG_HI; /* Configuration Register High */
  82. DW_REG(SGR);
  83. DW_REG(DSR);
  84. };
  85. struct dw_dma_irq_regs {
  86. DW_REG(XFER);
  87. DW_REG(BLOCK);
  88. DW_REG(SRC_TRAN);
  89. DW_REG(DST_TRAN);
  90. DW_REG(ERROR);
  91. };
  92. struct dw_dma_regs {
  93. /* per-channel registers */
  94. struct dw_dma_chan_regs CHAN[DW_DMA_MAX_NR_CHANNELS];
  95. /* irq handling */
  96. struct dw_dma_irq_regs RAW; /* r */
  97. struct dw_dma_irq_regs STATUS; /* r (raw & mask) */
  98. struct dw_dma_irq_regs MASK; /* rw (set = irq enabled) */
  99. struct dw_dma_irq_regs CLEAR; /* w (ack, affects "raw") */
  100. DW_REG(STATUS_INT); /* r */
  101. /* software handshaking */
  102. DW_REG(REQ_SRC);
  103. DW_REG(REQ_DST);
  104. DW_REG(SGL_REQ_SRC);
  105. DW_REG(SGL_REQ_DST);
  106. DW_REG(LAST_SRC);
  107. DW_REG(LAST_DST);
  108. /* miscellaneous */
  109. DW_REG(CFG);
  110. DW_REG(CH_EN);
  111. DW_REG(ID);
  112. DW_REG(TEST);
  113. /* optional encoded params, 0x3c8..0x3 */
  114. };
  115. /* Bitfields in CTL_LO */
  116. #define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
  117. #define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */
  118. #define DWC_CTLL_SRC_WIDTH(n) ((n)<<4)
  119. #define DWC_CTLL_DST_INC_MODE(n) ((n)<<7)
  120. #define DWC_CTLL_DST_INC (0<<7) /* DAR update/not */
  121. #define DWC_CTLL_DST_DEC (1<<7)
  122. #define DWC_CTLL_DST_FIX (2<<7)
  123. #define DWC_CTLL_SRC_INC_MODE(n) ((n)<<9)
  124. #define DWC_CTLL_SRC_INC (0<<9) /* SAR update/not */
  125. #define DWC_CTLL_SRC_DEC (1<<9)
  126. #define DWC_CTLL_SRC_FIX (2<<9)
  127. #define DWC_CTLL_DST_MSIZE(n) ((n)<<11) /* burst, #elements */
  128. #define DWC_CTLL_SRC_MSIZE(n) ((n)<<14)
  129. #define DWC_CTLL_S_GATH_EN (1 << 17) /* src gather, !FIX */
  130. #define DWC_CTLL_D_SCAT_EN (1 << 18) /* dst scatter, !FIX */
  131. #define DWC_CTLL_FC(n) ((n) << 20)
  132. #define DWC_CTLL_FC_M2M (0 << 20) /* mem-to-mem */
  133. #define DWC_CTLL_FC_M2P (1 << 20) /* mem-to-periph */
  134. #define DWC_CTLL_FC_P2M (2 << 20) /* periph-to-mem */
  135. #define DWC_CTLL_FC_P2P (3 << 20) /* periph-to-periph */
  136. /* plus 4 transfer types for peripheral-as-flow-controller */
  137. #define DWC_CTLL_DMS(n) ((n)<<23) /* dst master select */
  138. #define DWC_CTLL_SMS(n) ((n)<<25) /* src master select */
  139. #define DWC_CTLL_LLP_D_EN (1 << 27) /* dest block chain */
  140. #define DWC_CTLL_LLP_S_EN (1 << 28) /* src block chain */
  141. /* Bitfields in CTL_HI */
  142. #define DWC_CTLH_DONE 0x00001000
  143. #define DWC_CTLH_BLOCK_TS_MASK 0x00000fff
  144. /* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
  145. #define DWC_CFGL_CH_PRIOR_MASK (0x7 << 5) /* priority mask */
  146. #define DWC_CFGL_CH_PRIOR(x) ((x) << 5) /* priority */
  147. #define DWC_CFGL_CH_SUSP (1 << 8) /* pause xfer */
  148. #define DWC_CFGL_FIFO_EMPTY (1 << 9) /* pause xfer */
  149. #define DWC_CFGL_HS_DST (1 << 10) /* handshake w/dst */
  150. #define DWC_CFGL_HS_SRC (1 << 11) /* handshake w/src */
  151. #define DWC_CFGL_MAX_BURST(x) ((x) << 20)
  152. #define DWC_CFGL_RELOAD_SAR (1 << 30)
  153. #define DWC_CFGL_RELOAD_DAR (1 << 31)
  154. /* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
  155. #define DWC_CFGH_DS_UPD_EN (1 << 5)
  156. #define DWC_CFGH_SS_UPD_EN (1 << 6)
  157. /* Bitfields in SGR */
  158. #define DWC_SGR_SGI(x) ((x) << 0)
  159. #define DWC_SGR_SGC(x) ((x) << 20)
  160. /* Bitfields in DSR */
  161. #define DWC_DSR_DSI(x) ((x) << 0)
  162. #define DWC_DSR_DSC(x) ((x) << 20)
  163. /* Bitfields in CFG */
  164. #define DW_CFG_DMA_EN (1 << 0)
  165. #define DW_REGLEN 0x400
  166. /* Platform-configurable bits in CFG_HI */
  167. #define DWC_CFGH_FCMODE (1 << 0)
  168. #define DWC_CFGH_FIFO_MODE (1 << 1)
  169. #define DWC_CFGH_PROTCTL(x) ((x) << 2)
  170. #define DWC_CFGH_SRC_PER(x) ((x) << 7)
  171. #define DWC_CFGH_DST_PER(x) ((x) << 11)
  172. /* Platform-configurable bits in CFG_LO */
  173. #define DWC_CFGL_LOCK_CH_XFER (0 << 12) /* scope of LOCK_CH */
  174. #define DWC_CFGL_LOCK_CH_BLOCK (1 << 12)
  175. #define DWC_CFGL_LOCK_CH_XACT (2 << 12)
  176. #define DWC_CFGL_LOCK_BUS_XFER (0 << 14) /* scope of LOCK_BUS */
  177. #define DWC_CFGL_LOCK_BUS_BLOCK (1 << 14)
  178. #define DWC_CFGL_LOCK_BUS_XACT (2 << 14)
  179. #define DWC_CFGL_LOCK_CH (1 << 15) /* channel lockout */
  180. #define DWC_CFGL_LOCK_BUS (1 << 16) /* busmaster lockout */
  181. #define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */
  182. #define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */
  183. #define lift_shift_bit_num(bit_num) (1<<bit_num)
  184. #define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
  185. #define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v))
  186. #define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v))
  187. #define __raw_readb(a) (*(volatile unsigned char *)(a))
  188. #define __raw_readw(a) (*(volatile unsigned short *)(a))
  189. #define __raw_readl(a) (*(volatile unsigned int *)(a))
  190. #define min(a,b) (((a)<(b))?(a):(b))
  191. #define max(a,b) (((a)>(b))?(a):(b))
  192. #define dw_readl(dw, name) \
  193. __raw_readl(&(((struct dw_dma_regs *)dw->regs)->name))
  194. #define dw_writel(dw, name, val) \
  195. __raw_writel((val), &(((struct dw_dma_regs *)dw->regs)->name))
  196. #define dw_readw(dw, name) \
  197. __raw_readw(&(((struct dw_dma_regs *)dw->regs)->name))
  198. #define dw_writew(dw, name, val) \
  199. __raw_writew((val), &(((struct dw_dma_regs *)dw->regs)->name))
  200. #define CHANNEL0 (lift_shift_bit_num(0))
  201. #define CHANNEL1 (lift_shift_bit_num(1))
  202. #define CHANNEL2 (lift_shift_bit_num(2))
  203. #define CHANNEL3 (lift_shift_bit_num(3))
  204. #define channel_set_bit(dw, reg, mask) \
  205. dw_writel(dw, reg, ((mask) << 8) | (mask))
  206. #define channel_clear_bit(dw, reg, mask) \
  207. dw_writel(dw, reg, ((mask) << 8) | 0)
  208. /****************************************************************************
  209. * ADT section
  210. * add definition of user defined Data Type that only be used in this file here
  211. ***************************************************************************/
  212. struct dw_dma{
  213. //vadd
  214. void *regs;
  215. //padd
  216. rt_uint32_t paddr;
  217. rt_uint32_t irq;
  218. rt_uint32_t channel_max_number;
  219. #define CONTROLLER_STATUS_CLOSED (0)
  220. #define CONTROLLER_STATUS_OPEN (1)
  221. rt_uint32_t controller_status;
  222. #define FH81_DMA_INIT_NOT_YET (0)
  223. #define FH81_DMA_INIT_ALREADY (1)
  224. rt_uint32_t init;
  225. rt_uint32_t id;
  226. char *name;
  227. rt_uint32_t channel_work_done;
  228. };
  229. struct dma_channel {
  230. #define CHANNEL_STATUS_CLOSED (0)
  231. #define CHANNEL_STATUS_OPEN (1)
  232. #define CHANNEL_STATUS_IDLE (2)
  233. #define CHANNEL_STATUS_BUSY (3)
  234. rt_uint32_t channel_status; //open, busy ,closed
  235. rt_uint32_t desc_trans_size;
  236. //isr will set it complete.
  237. struct rt_completion transfer_completion;
  238. //add lock,when set the channel.lock it
  239. struct rt_semaphore channel_lock;
  240. //struct rt_mutex lock;
  241. //rt_enter_critical();
  242. rt_list_t queue;
  243. //active transfer now!!!
  244. struct dma_transfer *active_trans;
  245. #define SINGLE_TRANSFER (0)
  246. #define CYCLIC_TRANSFER (1)
  247. #define DEFAULT_TRANSFER SINGLE_TRANSFER
  248. rt_uint32_t open_flag;
  249. //
  250. //new add para...
  251. rt_uint32_t desc_total_no;
  252. rt_uint32_t free_index;
  253. rt_uint32_t used_index;
  254. rt_uint32_t desc_left_cnt;
  255. rt_uint32_t allign_malloc;
  256. struct dw_lli *base_lli;
  257. };
  258. struct fh81_dma{
  259. //core use ,this must be the first para!!!!
  260. struct rt_dma_device parent;
  261. //myown
  262. struct dw_dma dwc;
  263. //channel obj
  264. struct dma_channel dma_channel[FH81_MAX_CHANNEL];
  265. //struct rt_workqueue* isr_workqueue;
  266. //struct rt_work *isr_work;
  267. };
  268. #define list_for_each_entry_safe(pos, n, head, member) \
  269. for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
  270. n = rt_list_entry(pos->member.next, typeof(*pos), member); \
  271. &pos->member != (head); \
  272. pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
  273. /******************************************************************************
  274. * Function prototype section
  275. * add prototypes for all functions called by this file,execepting those
  276. * declared in header file
  277. *****************************************************************************/
  278. /*****************************************************************************
  279. * Global variables section - Exported
  280. * add declaration of global variables that will be exported here
  281. * e.g.
  282. * int8_t foo;
  283. ****************************************************************************/
  284. /*****************************************************************************
  285. * static fun;
  286. *****************************************************************************/
  287. static rt_err_t init (struct rt_dma_device *dma);
  288. static rt_err_t control (struct rt_dma_device *dma, int cmd, void *arg);
  289. static void rt_fh_dma_cyclic_stop(struct dma_transfer *p);
  290. static void rt_fh_dma_cyclic_start(struct dma_transfer *p);
  291. static void rt_fh_dma_cyclic_prep(struct fh81_dma * fh81_dma_p,struct dma_transfer *p);
  292. static void rt_fh_dma_cyclic_free(struct dma_transfer *p);
  293. static struct rt_dma_ops fh81_dma_ops =
  294. {
  295. init,
  296. control
  297. };
  298. /*****************************************************************************
  299. * Global variables section - Local
  300. * define global variables(will be refered only in this file) here,
  301. * static keyword should be used to limit scope of local variable to this file
  302. * e.g.
  303. * static uint8_t ufoo;
  304. *****************************************************************************/
  305. static struct fh81_dma fh81_dma_controller[DMA_CONTROLLER_NUMBER] = {0};
  306. /* function body */
  307. /*****************************************************************************
  308. * Description:
  309. * add funtion description here
  310. * Parameters:
  311. * description for each argument, new argument starts at new line
  312. * Return:
  313. * what does this function returned?
  314. *****************************************************************************/
  315. static rt_uint32_t allign_func(rt_uint32_t in_addr,rt_uint32_t allign_size){
  316. return (in_addr + allign_size-1) & (~(allign_size - 1));
  317. }
  318. struct dw_lli * get_desc(struct fh81_dma *p_dma,struct dma_transfer *p_transfer,rt_uint32_t lli_size){
  319. struct dw_lli * ret_lli;
  320. rt_uint32_t free_index;
  321. rt_uint32_t allign_left;
  322. rt_uint32_t totoal_desc;
  323. rt_uint32_t actual_get_desc;
  324. rt_uint32_t totoal_free_desc;
  325. totoal_free_desc = p_dma->dma_channel[p_transfer->channel_number].desc_left_cnt;
  326. free_index = p_dma->dma_channel[p_transfer->channel_number].free_index;
  327. totoal_desc = p_dma->dma_channel[p_transfer->channel_number].desc_total_no;
  328. allign_left = totoal_desc - free_index;
  329. //check first..
  330. if(totoal_free_desc < lli_size){
  331. rt_kprintf("not enough desc to get...\n");
  332. rt_kprintf("get size is %d,left is %d\n",lli_size,totoal_free_desc);
  333. return RT_NULL;
  334. }
  335. //rt_kprintf("get desc in...\n");
  336. //rt_kprintf("lli size is %d\n",lli_size);
  337. if(lli_size > allign_left){
  338. //if allign desc not enough...just reset null....
  339. if((totoal_free_desc - allign_left) < lli_size){
  340. rt_kprintf("not enough desc to get...\n");
  341. rt_kprintf("app need size is %d, totoal left is %d, allign left is %d\n",lli_size,totoal_free_desc,allign_left);
  342. rt_kprintf("from head to get desc size is %d, actual get is %d\n",(totoal_free_desc - allign_left),(allign_left +lli_size));
  343. return RT_NULL;
  344. }
  345. else{
  346. actual_get_desc = allign_left +lli_size;
  347. free_index = 0;
  348. }
  349. }
  350. //ret_lli = &p_dma->dma_channel[p_transfer->channel_number].base_lli[free_index];
  351. ret_lli = &p_dma->dma_channel[p_transfer->channel_number].base_lli[free_index];
  352. // rt_kprintf("get desc base index addr:%08x\n",(rt_uint32_t)&p_dma->dma_channel[p_transfer->channel_number].base_lli[0]);
  353. // rt_kprintf("get desc free index addr:%08x\n",(rt_uint32_t)ret_lli);
  354. // rt_kprintf("get desc request size:%08x\n",lli_size);
  355. // rt_kprintf("get desc total size:%08x\n",p_dma->dma_channel[p_transfer->channel_number].desc_total_no);
  356. // rt_kprintf("one desc size is:%08x\n",sizeof( struct dw_lli));
  357. p_dma->dma_channel[p_transfer->channel_number].free_index += actual_get_desc;
  358. //rt_kprintf("get desc free index addr:%08x\n",(rt_uint32_t)&p_dma->dma_channel[p_transfer->channel_number].base_lli[p_dma->dma_channel[p_transfer->channel_number].free_index]);
  359. p_dma->dma_channel[p_transfer->channel_number].free_index %= p_dma->dma_channel[p_transfer->channel_number].desc_total_no;
  360. p_dma->dma_channel[p_transfer->channel_number].desc_left_cnt -= actual_get_desc;
  361. p_transfer->lli_size = lli_size;
  362. p_transfer->actual_lli_size = actual_get_desc;
  363. return ret_lli;
  364. }
  365. rt_uint32_t put_desc(struct fh81_dma *p_dma,struct dma_transfer *p_transfer){
  366. struct dw_lli * ret_lli;
  367. rt_uint32_t used_index;
  368. rt_uint32_t lli_size;
  369. //rt_kprintf("put desc in...\n");
  370. used_index = p_dma->dma_channel[p_transfer->channel_number].used_index;
  371. lli_size = p_transfer->actual_lli_size;
  372. p_dma->dma_channel[p_transfer->channel_number].used_index += lli_size;
  373. p_dma->dma_channel[p_transfer->channel_number].used_index %= p_dma->dma_channel[p_transfer->channel_number].desc_total_no;
  374. p_dma->dma_channel[p_transfer->channel_number].desc_left_cnt += lli_size;
  375. p_transfer->lli_size = 0;
  376. p_transfer->actual_lli_size = 0;
  377. return 0;
  378. }
  379. /*****************************************************************************
  380. * Description:
  381. * add funtion description here
  382. * Parameters:
  383. * description for each argument, new argument starts at new line
  384. * Return:
  385. * what does this function returned?
  386. *****************************************************************************/
  387. static rt_err_t init (struct rt_dma_device *dma){
  388. //init the clk table
  389. struct fh81_dma *my_own = (struct fh81_dma *)dma->parent.user_data;
  390. FH_DMA_DEBUG("my_own value:0x%x\n",(rt_uint32_t)my_own);
  391. //check the user data
  392. RT_ASSERT(my_own != RT_NULL);
  393. return RT_EOK;
  394. }
  395. /*****************************************************************************
  396. * Description:
  397. * add funtion description here
  398. * Parameters:
  399. * description for each argument, new argument starts at new line
  400. * Return:
  401. * what does this function returned?
  402. *****************************************************************************/
  403. static void handle_dma_open(struct fh81_dma *p_dma){
  404. rt_uint32_t i;
  405. struct dw_dma *temp_dwc;
  406. temp_dwc = &p_dma->dwc;
  407. dw_writel(temp_dwc, CFG, 1);
  408. p_dma->dwc.controller_status = CONTROLLER_STATUS_OPEN;
  409. }
  410. /*****************************************************************************
  411. * Description:
  412. * add funtion description here
  413. * Parameters:
  414. * description for each argument, new argument starts at new line
  415. * Return:
  416. * what does this function returned?
  417. *****************************************************************************/
  418. static void handle_dma_close(struct fh81_dma *p_dma){
  419. rt_uint32_t i;
  420. struct dw_dma *temp_dwc;
  421. temp_dwc = &p_dma->dwc;
  422. //take lock
  423. for(i=0;i<p_dma->dwc.channel_max_number;i++){
  424. rt_sem_take(&p_dma->dma_channel[i].channel_lock, RT_WAITING_FOREVER);
  425. channel_clear_bit(temp_dwc, CH_EN, lift_shift_bit_num(i));
  426. p_dma->dma_channel[i].channel_status = CHANNEL_STATUS_CLOSED;
  427. }
  428. dw_writel(temp_dwc, CFG, 0);
  429. p_dma->dwc.controller_status = CONTROLLER_STATUS_CLOSED;
  430. //release lock
  431. for(i=0;i<p_dma->dwc.channel_max_number;i++){
  432. rt_sem_release(&p_dma->dma_channel[i].channel_lock);
  433. }
  434. //destroy the workqueue..
  435. //rt_workqueue_destroy(p_dma->isr_workqueue);
  436. }
  437. /*****************************************************************************
  438. * Description:
  439. * add funtion description here
  440. * Parameters:
  441. * description for each argument, new argument starts at new line
  442. * Return:
  443. * what does this function returned?
  444. *****************************************************************************/
  445. #define CHANNEL_REAL_FREE (0)
  446. #define CHANNEL_NOT_FREE (1)
  447. static rt_uint32_t check_channel_real_free(struct fh81_dma *p_dma,rt_uint32_t channel_number){
  448. struct dw_dma *temp_dwc;
  449. temp_dwc = &p_dma->dwc;
  450. rt_uint32_t ret_status;
  451. RT_ASSERT(channel_number < p_dma->dwc.channel_max_number);
  452. ret_status = dw_readl(temp_dwc, CH_EN);
  453. if(ret_status & lift_shift_bit_num(channel_number)){
  454. //the channel is still busy!!!error here
  455. //FH_DMA_DEBUG("auto request channel error\n");
  456. return CHANNEL_NOT_FREE;
  457. }
  458. return CHANNEL_REAL_FREE;
  459. }
  460. /*****************************************************************************
  461. * Description:
  462. * add funtion description here
  463. * Parameters:
  464. * description for each argument, new argument starts at new line
  465. * Return:
  466. * what does this function returned?
  467. *****************************************************************************/
  468. static rt_err_t handle_request_channel(struct fh81_dma *p_dma,struct dma_transfer *p_transfer){
  469. rt_uint32_t i;
  470. struct dw_dma *temp_dwc;
  471. temp_dwc = &p_dma->dwc;
  472. rt_err_t ret_status = RT_EOK;
  473. //handle if auto check channel...
  474. if(p_transfer->channel_number == AUTO_FIND_CHANNEL){
  475. //check each channel lock,find a free channel...
  476. for(i=0;i<p_dma->dwc.channel_max_number;i++){
  477. ret_status = rt_sem_trytake(&p_dma->dma_channel[i].channel_lock);
  478. if(ret_status == RT_EOK){
  479. break;
  480. }
  481. }
  482. if(i < p_dma->dwc.channel_max_number){
  483. ret_status = check_channel_real_free(p_dma,i);
  484. if(ret_status!= CHANNEL_REAL_FREE){
  485. FH_DMA_DEBUG("auto request channel error\n");
  486. RT_ASSERT(ret_status == CHANNEL_REAL_FREE);
  487. }
  488. //caution : channel is already locked here....
  489. p_transfer->channel_number = i;
  490. //bind to the controller.
  491. //p_transfer->dma_controller = p_dma;
  492. p_dma->dma_channel[i].channel_status = CHANNEL_STATUS_OPEN;
  493. }
  494. else
  495. return -RT_ENOMEM;
  496. }
  497. // request channel by user
  498. else{
  499. //
  500. RT_ASSERT(p_transfer->channel_number < p_dma->dwc.channel_max_number);
  501. ret_status = rt_sem_take(&p_dma->dma_channel[p_transfer->channel_number].channel_lock, RT_TICK_PER_SECOND*50);
  502. if(ret_status != RT_EOK)
  503. return -RT_ENOMEM;
  504. //rt_enter_critical();
  505. ret_status = check_channel_real_free(p_dma,p_transfer->channel_number);
  506. if(ret_status!= CHANNEL_REAL_FREE){
  507. FH_DMA_DEBUG("user request channel error\n");
  508. RT_ASSERT(ret_status == CHANNEL_REAL_FREE);
  509. }
  510. //bind to the controller
  511. //p_transfer->dma_controller = p_dma;
  512. p_dma->dma_channel[p_transfer->channel_number].channel_status = CHANNEL_STATUS_OPEN;
  513. //rt_exit_critical();
  514. }
  515. //malloc desc for this one channel...
  516. //fix me....
  517. p_dma->dma_channel[p_transfer->channel_number].allign_malloc = (rt_uint32_t) rt_malloc(
  518. (p_dma->dma_channel[p_transfer->channel_number].desc_total_no
  519. * sizeof(struct dw_lli)) + CACHE_LINE_SIZE);
  520. if(!p_dma->dma_channel[p_transfer->channel_number].allign_malloc){
  521. //release channel
  522. rt_kprintf("[dma]: no mem to malloc channel%d desc..\n",p_transfer->channel_number);
  523. p_dma->dma_channel[p_transfer->channel_number].channel_status = CHANNEL_STATUS_CLOSED;
  524. rt_sem_release(&p_dma->dma_channel[p_transfer->channel_number].channel_lock);
  525. return -RT_ENOMEM;
  526. }
  527. p_dma->dma_channel[p_transfer->channel_number].base_lli =
  528. (struct dw_lli *) allign_func(
  529. p_dma->dma_channel[p_transfer->channel_number].allign_malloc,
  530. CACHE_LINE_SIZE);
  531. FH_DMA_DEBUG("dma desc addr is %x\n",(rt_uint32_t)p_dma->dma_channel[p_transfer->channel_number].base_lli);
  532. //t1 = (UINT32)rt_malloc(GMAC_TX_RING_SIZE * sizeof(Gmac_Tx_DMA_Descriptors) + CACHE_LINE_SIZE);
  533. if(!p_dma->dma_channel[p_transfer->channel_number].base_lli){
  534. FH_DMA_DEBUG("request desc failed..\n");
  535. RT_ASSERT(p_dma->dma_channel[p_transfer->channel_number].base_lli != RT_NULL);
  536. }
  537. if((rt_uint32_t)p_dma->dma_channel[p_transfer->channel_number].base_lli % 32){
  538. rt_kprintf("malloc is not cache allign..");
  539. }
  540. //rt_memset((void *)dma_trans_desc->first_lli, 0, lli_size * sizeof(struct dw_lli));
  541. rt_memset((void *) p_dma->dma_channel[p_transfer->channel_number].base_lli,
  542. 0,
  543. p_dma->dma_channel[p_transfer->channel_number].desc_total_no
  544. * sizeof(struct dw_lli));
  545. p_dma->dma_channel[p_transfer->channel_number].desc_left_cnt = p_dma->dma_channel[p_transfer->channel_number].desc_total_no;
  546. p_dma->dma_channel[p_transfer->channel_number].free_index = 0;
  547. p_dma->dma_channel[p_transfer->channel_number].used_index = 0;
  548. return RT_EOK;
  549. }
  550. /*****************************************************************************
  551. * Description:
  552. * add funtion description here
  553. * Parameters:
  554. * description for each argument, new argument starts at new line
  555. * Return:
  556. * what does this function returned?
  557. *****************************************************************************/
  558. static rt_uint32_t handle_release_channel(struct fh81_dma *p_dma,struct dma_transfer *p_transfer){
  559. rt_uint32_t i;
  560. struct dw_dma *temp_dwc;
  561. temp_dwc = &p_dma->dwc;
  562. rt_uint32_t ret_status;
  563. //rt_enter_critical();
  564. ret_status = p_dma->dma_channel[p_transfer->channel_number].channel_status;
  565. RT_ASSERT(p_transfer->channel_number < p_dma->dwc.channel_max_number);
  566. if(ret_status == CHANNEL_STATUS_CLOSED){
  567. FH_DMA_DEBUG("release channel error,reason: release a closed channel!!\n");
  568. RT_ASSERT(ret_status != CHANNEL_STATUS_CLOSED);
  569. }
  570. channel_clear_bit(temp_dwc, CH_EN, lift_shift_bit_num(p_transfer->channel_number));
  571. rt_sem_release(&p_dma->dma_channel[p_transfer->channel_number].channel_lock);
  572. //p_transfer->dma_controller = RT_NULL;
  573. p_dma->dma_channel[p_transfer->channel_number].channel_status = CHANNEL_STATUS_CLOSED;
  574. p_dma->dma_channel[p_transfer->channel_number].open_flag = DEFAULT_TRANSFER;
  575. //rt_exit_critical();
  576. //release this channel malloc mem...
  577. //fix me.....
  578. rt_free((void *)p_dma->dma_channel[p_transfer->channel_number].allign_malloc);
  579. p_dma->dma_channel[p_transfer->channel_number].allign_malloc = RT_NULL;
  580. p_dma->dma_channel[p_transfer->channel_number].base_lli = RT_NULL;
  581. p_dma->dma_channel[p_transfer->channel_number].desc_left_cnt = p_dma->dma_channel[p_transfer->channel_number].desc_total_no;
  582. p_dma->dma_channel[p_transfer->channel_number].free_index = 0;
  583. p_dma->dma_channel[p_transfer->channel_number].used_index = 0;
  584. return RT_EOK;
  585. }
  586. static rt_uint32_t cal_lli_size(struct dma_transfer *p_transfer){
  587. RT_ASSERT(p_transfer != RT_NULL);
  588. RT_ASSERT(p_transfer->dma_controller != RT_NULL);
  589. RT_ASSERT(p_transfer->src_width <= DW_DMA_SLAVE_WIDTH_32BIT);
  590. rt_uint32_t lli_number = 0;
  591. rt_uint32_t channel_max_trans_per_lli = 0;
  592. channel_max_trans_per_lli = p_transfer->dma_controller->dma_channel[p_transfer->channel_number].desc_trans_size;
  593. lli_number = (p_transfer->trans_len % channel_max_trans_per_lli) ? 1:0;
  594. lli_number += p_transfer->trans_len / channel_max_trans_per_lli;
  595. return lli_number;
  596. }
  597. static void dump_lli(struct dw_lli *p_lli){
  598. FH_DMA_DEBUG("link_mem padd:0x%x\n sar:0x%x\n dar:0x%x\n llp:0x%x\n ctllo:0x%x\n ctlhi:0x%x\n sstat:0x%x\n dstat:0x%x\n",
  599. (rt_uint32_t)p_lli,p_lli->sar, p_lli->dar, p_lli->llp,
  600. p_lli->ctllo, p_lli->ctlhi,p_lli->sstat,p_lli->dstat);
  601. }
  602. /*****************************************************************************
  603. * Description:
  604. * add funtion description here
  605. * Parameters:
  606. * description for each argument, new argument starts at new line
  607. * Return:
  608. * what does this function returned?
  609. *****************************************************************************/
  610. static void handle_single_transfer(struct fh81_dma *p_dma,struct dma_transfer *p_transfer){
  611. rt_uint32_t i;
  612. struct dw_dma *temp_dwc;
  613. temp_dwc = &p_dma->dwc;
  614. volatile rt_uint32_t ret_status;
  615. rt_list_t *p_controller_list;
  616. rt_uint32_t lli_size,max_trans_size;
  617. struct dw_lli *p_lli = RT_NULL;
  618. struct dma_transfer *dma_trans_desc;
  619. struct dma_transfer *_dma_trans_desc;
  620. rt_uint32_t temp_src_add;
  621. rt_uint32_t temp_dst_add;
  622. rt_uint32_t trans_total_len = 0;
  623. rt_uint32_t temp_trans_size = 0;
  624. //rt_uint32_t dma_channl_no = 0;
  625. RT_ASSERT(p_transfer->channel_number < p_dma->dwc.channel_max_number);
  626. RT_ASSERT(p_transfer->dma_number < DMA_CONTROLLER_NUMBER);
  627. RT_ASSERT(&fh81_dma_controller[p_transfer->dma_number] == p_dma);
  628. //when the dma transfer....the lock should be 0!!!!
  629. //or user may not request the channel...
  630. RT_ASSERT(p_dma->dma_channel[p_transfer->channel_number].channel_lock.value == 0);
  631. ret_status = p_dma->dma_channel[p_transfer->channel_number].channel_status;
  632. if(ret_status == CHANNEL_STATUS_CLOSED){
  633. FH_DMA_DEBUG("transfer error,reason: use a closed channel..\n");
  634. RT_ASSERT(ret_status != CHANNEL_STATUS_CLOSED);
  635. }
  636. p_transfer->dma_controller = p_dma;
  637. rt_list_init(&p_transfer->transfer_list);
  638. max_trans_size = p_transfer->dma_controller->dma_channel[p_transfer->channel_number].desc_trans_size;
  639. //add transfer to the controller's queue list
  640. //here should insert before and handle after....this could be a fifo...
  641. rt_list_insert_before(&p_dma->dma_channel[p_transfer->channel_number].queue , &p_transfer->transfer_list);
  642. p_controller_list = &p_dma->dma_channel[p_transfer->channel_number].queue;
  643. //here the driver could make a queue to cache the transfer and kick a thread to handle the queue~~~
  644. //but now,this is a easy version...,just handle the transfer now!!!
  645. list_for_each_entry_safe(dma_trans_desc, _dma_trans_desc, p_controller_list, transfer_list) {
  646. //the dma controller could see the active transfer .....
  647. p_transfer->dma_controller->dma_channel[p_transfer->channel_number].active_trans = dma_trans_desc;
  648. trans_total_len = p_transfer->trans_len;
  649. //handle desc
  650. //step1:cal lli size...
  651. lli_size = cal_lli_size(dma_trans_desc);
  652. //step2:malloc lli_size mem
  653. //dma_trans_desc->first_lli = (struct dw_lli *)rt_malloc(lli_size * sizeof(struct dw_lli));
  654. dma_trans_desc->first_lli = get_desc(p_dma,p_transfer,lli_size);
  655. //not enough mem..
  656. if(dma_trans_desc->first_lli == RT_NULL){
  657. FH_DMA_DEBUG("transfer error,reason: not enough mem..\n");
  658. RT_ASSERT(dma_trans_desc->first_lli != RT_NULL);
  659. }
  660. //bug here....
  661. rt_memset((void *)dma_trans_desc->first_lli, 0, lli_size * sizeof(struct dw_lli));
  662. p_lli = dma_trans_desc->first_lli;
  663. //warnning!!!!must check if the add is 32bits ally...
  664. RT_ASSERT(((rt_uint32_t)p_lli & 0x03) == 0);
  665. RT_ASSERT(dma_trans_desc->dst_inc_mode <=DW_DMA_SLAVE_FIX);
  666. RT_ASSERT(dma_trans_desc->src_inc_mode <=DW_DMA_SLAVE_FIX);
  667. //step3: set the mem..
  668. for(i=0;i<lli_size;i++){
  669. //parse trans para...
  670. //para add:
  671. switch(dma_trans_desc->dst_inc_mode){
  672. case DW_DMA_SLAVE_INC:
  673. temp_dst_add = dma_trans_desc->dst_add + i * max_trans_size * (1<<dma_trans_desc->dst_width);
  674. break;
  675. case DW_DMA_SLAVE_DEC:
  676. temp_dst_add = dma_trans_desc->dst_add - i * max_trans_size * (1<<dma_trans_desc->dst_width);
  677. break;
  678. case DW_DMA_SLAVE_FIX:
  679. temp_dst_add = dma_trans_desc->dst_add;
  680. break;
  681. }
  682. switch(dma_trans_desc->src_inc_mode){
  683. case DW_DMA_SLAVE_INC:
  684. temp_src_add = dma_trans_desc->src_add + i * max_trans_size * (1<<dma_trans_desc->src_width);
  685. break;
  686. case DW_DMA_SLAVE_DEC:
  687. temp_src_add = dma_trans_desc->src_add - i * max_trans_size * (1<<dma_trans_desc->src_width);
  688. break;
  689. case DW_DMA_SLAVE_FIX:
  690. temp_src_add = dma_trans_desc->src_add ;
  691. break;
  692. }
  693. p_lli[i].sar = temp_src_add;
  694. p_lli[i].dar = temp_dst_add;
  695. //para ctl
  696. temp_trans_size = (trans_total_len / max_trans_size)? max_trans_size : (trans_total_len % max_trans_size);
  697. trans_total_len -= temp_trans_size;
  698. RT_ASSERT(dma_trans_desc->dst_width <=DW_DMA_SLAVE_WIDTH_32BIT);
  699. RT_ASSERT(dma_trans_desc->src_width <=DW_DMA_SLAVE_WIDTH_32BIT);
  700. RT_ASSERT(dma_trans_desc->dst_msize <=DW_DMA_SLAVE_MSIZE_256);
  701. RT_ASSERT(dma_trans_desc->src_msize <=DW_DMA_SLAVE_MSIZE_256);
  702. RT_ASSERT(dma_trans_desc->fc_mode <=DMA_P2P);
  703. p_lli[i].ctllo = DWC_CTLL_INT_EN|DWC_CTLL_DST_WIDTH(dma_trans_desc->dst_width)|DWC_CTLL_SRC_WIDTH(dma_trans_desc->src_width)
  704. |DWC_CTLL_DST_INC_MODE(dma_trans_desc->dst_inc_mode)|DWC_CTLL_SRC_INC_MODE(dma_trans_desc->src_inc_mode)
  705. |DWC_CTLL_DST_MSIZE(dma_trans_desc->dst_msize)|DWC_CTLL_SRC_MSIZE(dma_trans_desc->src_msize)|DWC_CTLL_FC(dma_trans_desc->fc_mode)
  706. |DWC_CTLL_DMS(0)|DWC_CTLL_SMS(0);
  707. //block size
  708. p_lli[i].ctlhi = temp_trans_size;
  709. if(trans_total_len > 0){
  710. p_lli[i].llp = (rt_uint32_t)&p_lli[i+1];
  711. p_lli[i].ctllo |= DWC_CTLL_LLP_D_EN|DWC_CTLL_LLP_S_EN;
  712. }
  713. //flush cache to mem
  714. mmu_clean_invalidated_dcache((rt_uint32_t)&p_lli[i],sizeof(struct dw_lli));
  715. dump_lli(&p_lli[i]);
  716. }
  717. //clear the isr status
  718. //set the dma config reg
  719. //clear cfg reload reg
  720. //ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  721. //ret_status &= ~(DWC_CFGL_RELOAD_SAR|DWC_CFGL_RELOAD_DAR);
  722. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,0);
  723. //set the first link add
  724. //ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].LLP);
  725. ret_status = 0;
  726. ret_status = (rt_uint32_t)&p_lli[0];
  727. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].LLP,ret_status);
  728. //set link enable
  729. //ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CTL_LO);
  730. ret_status = 0;
  731. ret_status =DWC_CTLL_LLP_D_EN|DWC_CTLL_LLP_S_EN;
  732. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CTL_LO,ret_status);
  733. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CTL_HI,0);
  734. //set handshaking
  735. RT_ASSERT(dma_trans_desc->dst_hs <= DMA_SW_HANDSHAKING);
  736. RT_ASSERT(dma_trans_desc->src_hs <= DMA_SW_HANDSHAKING);
  737. if(dma_trans_desc->dst_hs == DMA_SW_HANDSHAKING){
  738. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  739. ret_status |= DWC_CFGL_HS_DST;
  740. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  741. }
  742. else{
  743. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  744. ret_status &= ~DWC_CFGL_HS_DST;
  745. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  746. }
  747. if(dma_trans_desc->src_hs == DMA_SW_HANDSHAKING){
  748. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  749. ret_status |= DWC_CFGL_HS_SRC;
  750. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  751. }
  752. else{
  753. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  754. ret_status &= ~DWC_CFGL_HS_SRC;
  755. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  756. }
  757. //only hw handshaking need this..
  758. switch(dma_trans_desc->fc_mode){
  759. case DMA_M2M:
  760. break;
  761. case DMA_M2P:
  762. //set dst per...
  763. RT_ASSERT(dma_trans_desc->dst_per < DMA_HW_HS_END);
  764. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  765. //clear 43 ~ 46 bit
  766. ret_status &= ~0x7800;
  767. ret_status |= DWC_CFGH_DST_PER(dma_trans_desc->dst_per);
  768. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  769. //DWC_CFGH_SRC_PER
  770. break;
  771. case DMA_P2M:
  772. //set src per...
  773. RT_ASSERT(dma_trans_desc->src_per < DMA_HW_HS_END);
  774. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  775. //clear 39 ~ 42 bit
  776. ret_status &= ~0x780;
  777. ret_status |= DWC_CFGH_SRC_PER(dma_trans_desc->src_per);
  778. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  779. break;
  780. case DMA_P2P:
  781. //set src and dst..
  782. RT_ASSERT(dma_trans_desc->dst_per < DMA_HW_HS_END);
  783. RT_ASSERT(dma_trans_desc->src_per < DMA_HW_HS_END);
  784. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  785. ret_status &= ~0x7800;
  786. ret_status &= ~0x780;
  787. ret_status |= DWC_CFGH_SRC_PER(dma_trans_desc->src_per) | DWC_CFGH_DST_PER(dma_trans_desc->dst_per);
  788. dw_writel(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  789. break;
  790. default:
  791. break;
  792. }
  793. dma_trans_desc->dma_controller->dma_channel[dma_trans_desc->channel_number].channel_status = CHANNEL_STATUS_BUSY;
  794. //enable isr...
  795. channel_set_bit(temp_dwc, MASK.XFER, lift_shift_bit_num(dma_trans_desc->channel_number));
  796. channel_set_bit(temp_dwc, MASK.ERROR, lift_shift_bit_num(dma_trans_desc->channel_number));
  797. //close
  798. channel_clear_bit(temp_dwc, MASK.BLOCK, lift_shift_bit_num(dma_trans_desc->channel_number));
  799. dw_writel(temp_dwc, CLEAR.XFER, 1<<(dma_trans_desc->channel_number));
  800. dw_writel(temp_dwc, CLEAR.BLOCK, 1<<(dma_trans_desc->channel_number));
  801. dw_writel(temp_dwc, CLEAR.SRC_TRAN, 1<<(dma_trans_desc->channel_number));
  802. dw_writel(temp_dwc, CLEAR.DST_TRAN, 1<<(dma_trans_desc->channel_number));
  803. dw_writel(temp_dwc, CLEAR.ERROR, 1<<(dma_trans_desc->channel_number));
  804. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  805. FH_DMA_DEBUG("cfg_hi value:0x%x\n",ret_status);
  806. ret_status = dw_readl(temp_dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  807. FH_DMA_DEBUG("cfg_low value:0x%x\n",ret_status);
  808. ret_status = dw_readl(temp_dwc, MASK.BLOCK);
  809. FH_DMA_DEBUG("mask block value:0x%x\n",ret_status);
  810. ret_status = dw_readl(temp_dwc, MASK.XFER);
  811. FH_DMA_DEBUG("mask xfer value:0x%x\n",ret_status);
  812. if(dma_trans_desc->prepare_callback){
  813. dma_trans_desc->prepare_callback(dma_trans_desc->prepare_para);
  814. }
  815. //enable the channle to transfer
  816. channel_set_bit(temp_dwc, CH_EN, lift_shift_bit_num(dma_trans_desc->channel_number));
  817. }
  818. }
  819. /*****************************************************************************
  820. * Description:
  821. * add funtion description here
  822. * Parameters:
  823. * description for each argument, new argument starts at new line
  824. * Return:
  825. * what does this function returned?
  826. *****************************************************************************/
  827. static rt_err_t control (struct rt_dma_device *dma, int cmd, void *arg){
  828. struct fh81_dma *my_own = (struct fh81_dma *)dma->parent.user_data;
  829. rt_uint32_t i;
  830. struct dw_dma *dwc;
  831. dwc = &my_own->dwc;
  832. rt_err_t ret = RT_EOK;
  833. struct dma_transfer *p_dma_transfer = (struct dma_transfer *)arg;
  834. //FH_DMA_DEBUG("p_dma_transfer value:0x%x\n",(rt_uint32_t)p_dma_transfer);
  835. RT_ASSERT(my_own != RT_NULL);
  836. RT_ASSERT(dwc != RT_NULL);
  837. switch(cmd){
  838. case RT_DEVICE_CTRL_DMA_OPEN:
  839. //open the controller..
  840. handle_dma_open(my_own);
  841. break;
  842. case RT_DEVICE_CTRL_DMA_CLOSE:
  843. //close the controller..
  844. handle_dma_close(my_own);
  845. break;
  846. case RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL:
  847. //request a channel for the user
  848. RT_ASSERT(p_dma_transfer != RT_NULL);
  849. ret = handle_request_channel(my_own,p_dma_transfer);
  850. break;
  851. case RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL:
  852. //release a channel
  853. RT_ASSERT(p_dma_transfer != RT_NULL);
  854. ret = handle_release_channel(my_own,p_dma_transfer);
  855. break;
  856. case RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER:
  857. //make a channel to transfer data.
  858. RT_ASSERT(p_dma_transfer != RT_NULL);
  859. //check if the dma channel is open,or return error.
  860. my_own->dma_channel[p_dma_transfer->channel_number].open_flag = SINGLE_TRANSFER;
  861. handle_single_transfer(my_own,p_dma_transfer);
  862. //then wait for the channel is complete..
  863. //caution that::we should be in the "rt_enter_critical()"when set the dma to work.
  864. break;
  865. case RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE:
  866. RT_ASSERT(p_dma_transfer != RT_NULL);
  867. my_own->dma_channel[p_dma_transfer->channel_number].open_flag = CYCLIC_TRANSFER;
  868. rt_fh_dma_cyclic_prep(my_own,p_dma_transfer);
  869. break;
  870. case RT_DEVICE_CTRL_DMA_CYCLIC_START:
  871. rt_fh_dma_cyclic_start(p_dma_transfer);
  872. break;
  873. case RT_DEVICE_CTRL_DMA_CYCLIC_STOP:
  874. rt_fh_dma_cyclic_stop(p_dma_transfer);
  875. break;
  876. case RT_DEVICE_CTRL_DMA_CYCLIC_FREE:
  877. rt_fh_dma_cyclic_free(p_dma_transfer);
  878. break;
  879. default:
  880. break;
  881. }
  882. return ret;
  883. }
  884. static void rt_fh81_dma_isr(int irq, void *param)
  885. {
  886. RT_ASSERT(irq == DMAC_IRQn);
  887. rt_uint32_t isr_channel_x,i,error,isr_channel_b;
  888. struct fh81_dma *my_own = (struct fh81_dma *)param;
  889. struct dw_dma *dwc;
  890. struct dma_transfer *p_transfer;
  891. dwc = &my_own->dwc;
  892. //p_transfer =
  893. //rt_kprintf("dma isr get in~~~\n");
  894. error = dw_readl(dwc,STATUS.ERROR);
  895. if(error != 0){
  896. FH_DMA_DEBUG("dma isr error!!!!\n");
  897. RT_ASSERT(error == RT_NULL);
  898. }
  899. isr_channel_x = dw_readl(dwc,STATUS.XFER);
  900. isr_channel_b = dw_readl(dwc,STATUS.BLOCK);
  901. //for single check the transfer status
  902. //check which channel...
  903. for(i=0;i<my_own->dwc.channel_max_number;i++){
  904. if(my_own->dma_channel[i].open_flag == SINGLE_TRANSFER){
  905. if(isr_channel_x & 1<<i){
  906. dw_writel(dwc, CLEAR.XFER, 1<<i);
  907. p_transfer = my_own->dma_channel[i].active_trans;
  908. if(p_transfer->complete_callback){
  909. p_transfer->complete_callback(p_transfer->complete_para);
  910. }
  911. p_transfer->dma_controller->dma_channel[p_transfer->channel_number].channel_status = CHANNEL_STATUS_IDLE;
  912. //here is a bug...do not free here
  913. //rt_free(p_transfer->first_lli);
  914. put_desc(my_own,p_transfer);
  915. rt_list_remove(&p_transfer->transfer_list);
  916. }
  917. }
  918. else if(my_own->dma_channel[i].open_flag == CYCLIC_TRANSFER){
  919. if(isr_channel_b & 1<<i){
  920. p_transfer = my_own->dma_channel[i].active_trans;
  921. dw_writel(dwc, CLEAR.BLOCK, 1<<(p_transfer->channel_number));
  922. if(p_transfer->complete_callback){
  923. p_transfer->complete_callback(p_transfer->complete_para);
  924. }
  925. }
  926. }
  927. }
  928. }
  929. /*****************************************************************************
  930. * Description:
  931. * add funtion description here
  932. * Parameters:
  933. * description for each argument, new argument starts at new line
  934. * Return:
  935. * what does this function returned?
  936. *****************************************************************************/
  937. const char *channel_lock_name[FH81_MAX_CHANNEL] = {
  938. "channel_0_lock",
  939. "channel_1_lock",
  940. "channel_2_lock",
  941. "channel_3_lock",
  942. };
  943. rt_err_t fh81_dma_register(struct fh81_dma * fh81_dma_p,
  944. char * dma_name){
  945. rt_uint32_t i;
  946. RT_ASSERT(fh81_dma_p != RT_NULL);
  947. RT_ASSERT(dma_name != RT_NULL);
  948. //RT_ASSERT(fh81_dma_p->dwc.init != FH81_DMA_INIT_ALREADY);
  949. if(fh81_dma_p->dwc.init == FH81_DMA_INIT_ALREADY)
  950. return 0;
  951. struct rt_dma_device *rt_dma;
  952. rt_dma = &fh81_dma_p->parent;
  953. rt_dma->ops = &fh81_dma_ops;
  954. //soc para set
  955. fh81_dma_p->dwc.name = dma_name;
  956. fh81_dma_p->dwc.regs =(void *)DMA_REG_BASE;
  957. fh81_dma_p->dwc.paddr = DMA_REG_BASE;
  958. fh81_dma_p->dwc.irq = DMAC_IRQn;
  959. fh81_dma_p->dwc.channel_max_number = FH81_MAX_CHANNEL;
  960. fh81_dma_p->dwc.controller_status = CONTROLLER_STATUS_CLOSED;
  961. fh81_dma_p->dwc.init = FH81_DMA_INIT_ALREADY;
  962. fh81_dma_p->dwc.id = 0;
  963. //channel set
  964. for(i=0;i<FH81_MAX_CHANNEL;i++){
  965. fh81_dma_p->dma_channel[i].channel_status = CHANNEL_STATUS_CLOSED;
  966. fh81_dma_p->dma_channel[i].desc_total_no = DESC_MAX_SIZE;
  967. //rt_completion_init(&(fh81_dma_p->dma_channel[i].transfer_completion));
  968. rt_list_init(&(fh81_dma_p->dma_channel[i].queue));
  969. fh81_dma_p->dma_channel[i].desc_trans_size = FH81_CHANNEL_MAX_TRANSFER_SIZE;
  970. rt_sem_init(&fh81_dma_p->dma_channel[i].channel_lock, channel_lock_name[i], 1, RT_IPC_FLAG_FIFO);
  971. }
  972. //isr
  973. rt_hw_interrupt_install(fh81_dma_p->dwc.irq, rt_fh81_dma_isr,
  974. (void *)fh81_dma_p, "dma_isr");
  975. rt_hw_interrupt_umask(fh81_dma_p->dwc.irq);
  976. return rt_hw_dma_register(rt_dma,dma_name,RT_DEVICE_FLAG_RDWR,fh81_dma_p);
  977. }
  978. static void rt_fh_dma_cyclic_stop(struct dma_transfer *p){
  979. struct fh81_dma *my_own = p->dma_controller;
  980. struct dw_dma *dwc;
  981. dwc = &my_own->dwc;
  982. channel_clear_bit(dwc, CH_EN, 1<<(p->channel_number));
  983. }
  984. static void rt_fh_dma_cyclic_start(struct dma_transfer *p){
  985. struct fh81_dma *my_own = p->dma_controller;
  986. struct dw_dma *dwc;
  987. dwc = &my_own->dwc;
  988. volatile uint32_t ret_status;
  989. struct dw_lli *p_lli = RT_NULL;
  990. p_lli = p->first_lli;
  991. //32bit ally
  992. RT_ASSERT(((uint32_t)p_lli & 0x03) == 0);
  993. dw_writel(dwc, CLEAR.XFER, 1<<(p->channel_number));
  994. dw_writel(dwc, CLEAR.BLOCK, 1<<(p->channel_number));
  995. dw_writel(dwc, CLEAR.ERROR, 1<<(p->channel_number));
  996. //enable isr
  997. channel_set_bit(dwc, MASK.BLOCK, lift_shift_bit_num(p->channel_number));
  998. //disable isr
  999. channel_clear_bit(dwc, MASK.XFER, lift_shift_bit_num(p->channel_number));
  1000. ret_status = dw_readl(dwc,CHAN[p->channel_number].CFG_LO);
  1001. ret_status &= ~(DWC_CFGL_RELOAD_SAR|DWC_CFGL_RELOAD_DAR);
  1002. dw_writel(dwc,CHAN[p->channel_number].CFG_LO,ret_status);
  1003. //set the first link add
  1004. ret_status = dw_readl(dwc,CHAN[p->channel_number].LLP);
  1005. ret_status = (uint32_t)&p_lli[0];
  1006. dw_writel(dwc,CHAN[p->channel_number].LLP,ret_status);
  1007. //set link enable
  1008. //ret_status = dw_readl(dwc,CHAN[p->channel_number].CTL_LO);
  1009. ret_status =DWC_CTLL_LLP_D_EN|DWC_CTLL_LLP_S_EN;
  1010. dw_writel(dwc,CHAN[p->channel_number].CTL_LO,ret_status);
  1011. //clear ctl_hi
  1012. dw_writel(dwc,CHAN[p->channel_number].CTL_HI,0);
  1013. //enable channle
  1014. channel_set_bit(dwc, CH_EN, 1<<(p->channel_number));
  1015. }
  1016. static void rt_fh_dma_cyclic_prep(struct fh81_dma * fh81_dma_p,struct dma_transfer *p) {
  1017. //bind the controller to the transfer
  1018. p->dma_controller = fh81_dma_p;
  1019. //bind active transfer
  1020. fh81_dma_p->dma_channel[p->channel_number].active_trans = p;
  1021. //p_transfer->dma_controller->dma_channel[p_transfer->channel_number].active_trans = dma_trans_desc;
  1022. struct fh81_dma *my_own = p->dma_controller;
  1023. struct dw_dma *dwc;
  1024. dwc = &my_own->dwc;
  1025. volatile uint32_t ret_status;
  1026. struct dw_lli *p_lli = RT_NULL;
  1027. uint32_t periods,i;
  1028. uint32_t temp_src_add;
  1029. uint32_t temp_dst_add;
  1030. uint32_t buf_len = p->trans_len;
  1031. uint32_t period_len = p->period_len;
  1032. struct dma_transfer * dma_trans_desc = p;
  1033. //check first...
  1034. RT_ASSERT(buf_len % period_len == 0);
  1035. //cal the periods...
  1036. periods = buf_len / period_len;
  1037. //get desc....
  1038. //dma_trans_desc->first_lli = (struct dw_lli *)rt_malloc(periods * sizeof(struct dw_lli));
  1039. dma_trans_desc->first_lli = get_desc(fh81_dma_p,dma_trans_desc,periods);
  1040. if(dma_trans_desc->first_lli == RT_NULL){
  1041. FH_DMA_DEBUG("transfer error,reason: not enough mem..\n");
  1042. RT_ASSERT(dma_trans_desc->first_lli != RT_NULL);
  1043. }
  1044. rt_memset((void *)dma_trans_desc->first_lli, 0, periods * sizeof(struct dw_lli));
  1045. p_lli = dma_trans_desc->first_lli;
  1046. RT_ASSERT(((uint32_t)p_lli & 0x03) == 0);
  1047. RT_ASSERT(dma_trans_desc->dst_inc_mode <=DW_DMA_SLAVE_FIX);
  1048. RT_ASSERT(dma_trans_desc->src_inc_mode <=DW_DMA_SLAVE_FIX);
  1049. //step3: set the mem..
  1050. for(i=0;i<periods;i++){
  1051. //parse trans para...
  1052. //para add:
  1053. switch(dma_trans_desc->dst_inc_mode){
  1054. case DW_DMA_SLAVE_INC:
  1055. temp_dst_add = dma_trans_desc->dst_add + i * period_len * (1<<dma_trans_desc->dst_width);
  1056. break;
  1057. case DW_DMA_SLAVE_DEC:
  1058. temp_dst_add = dma_trans_desc->dst_add - i * period_len * (1<<dma_trans_desc->dst_width);
  1059. break;
  1060. case DW_DMA_SLAVE_FIX:
  1061. temp_dst_add = dma_trans_desc->dst_add;
  1062. break;
  1063. }
  1064. switch(dma_trans_desc->src_inc_mode){
  1065. case DW_DMA_SLAVE_INC:
  1066. temp_src_add = dma_trans_desc->src_add + i * period_len * (1<<dma_trans_desc->src_width);
  1067. break;
  1068. case DW_DMA_SLAVE_DEC:
  1069. temp_src_add = dma_trans_desc->src_add - i * period_len * (1<<dma_trans_desc->src_width);
  1070. break;
  1071. case DW_DMA_SLAVE_FIX:
  1072. temp_src_add = dma_trans_desc->src_add ;
  1073. break;
  1074. }
  1075. p_lli[i].sar = temp_src_add;
  1076. p_lli[i].dar = temp_dst_add;
  1077. //para ctl
  1078. RT_ASSERT(dma_trans_desc->dst_width <=DW_DMA_SLAVE_WIDTH_32BIT);
  1079. RT_ASSERT(dma_trans_desc->src_width <=DW_DMA_SLAVE_WIDTH_32BIT);
  1080. RT_ASSERT(dma_trans_desc->dst_msize <=DW_DMA_SLAVE_MSIZE_256);
  1081. RT_ASSERT(dma_trans_desc->src_msize <=DW_DMA_SLAVE_MSIZE_256);
  1082. RT_ASSERT(dma_trans_desc->fc_mode <=DMA_P2P);
  1083. p_lli[i].ctllo = DWC_CTLL_INT_EN|DWC_CTLL_DST_WIDTH(dma_trans_desc->dst_width)|DWC_CTLL_SRC_WIDTH(dma_trans_desc->src_width)
  1084. |DWC_CTLL_DST_INC_MODE(dma_trans_desc->dst_inc_mode)|DWC_CTLL_SRC_INC_MODE(dma_trans_desc->src_inc_mode)
  1085. |DWC_CTLL_DST_MSIZE(dma_trans_desc->dst_msize)|DWC_CTLL_SRC_MSIZE(dma_trans_desc->src_msize)|DWC_CTLL_FC(dma_trans_desc->fc_mode)
  1086. |DWC_CTLL_DMS(0)|DWC_CTLL_SMS(0);
  1087. //block size
  1088. p_lli[i].ctlhi = period_len;
  1089. p_lli[i].llp = (uint32_t)&p_lli[i+1];
  1090. p_lli[i].ctllo |= DWC_CTLL_LLP_D_EN|DWC_CTLL_LLP_S_EN;
  1091. //flush cache to mem
  1092. mmu_clean_invalidated_dcache((uint32_t)&p_lli[i],sizeof(struct dw_lli));
  1093. dump_lli(&p_lli[i]);
  1094. }
  1095. //make a ring here
  1096. p_lli[periods -1 ].llp = (uint32_t)&p_lli[0];
  1097. mmu_clean_invalidated_dcache((uint32_t)&p_lli[periods -1 ],sizeof(struct dw_lli));
  1098. //parse the handshake
  1099. RT_ASSERT(dma_trans_desc->dst_hs <= DMA_SW_HANDSHAKING);
  1100. RT_ASSERT(dma_trans_desc->src_hs <= DMA_SW_HANDSHAKING);
  1101. //dst handshake
  1102. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,0);
  1103. ret_status = 0;
  1104. if(dma_trans_desc->dst_hs == DMA_SW_HANDSHAKING){
  1105. ret_status |= DWC_CFGL_HS_DST;
  1106. }
  1107. else{
  1108. ret_status &= ~DWC_CFGL_HS_DST;
  1109. }
  1110. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  1111. //src handshake
  1112. ret_status = dw_readl(dwc,CHAN[dma_trans_desc->channel_number].CFG_LO);
  1113. if(dma_trans_desc->src_hs == DMA_SW_HANDSHAKING){
  1114. ret_status |= DWC_CFGL_HS_SRC;
  1115. }
  1116. else{
  1117. ret_status &= ~DWC_CFGL_HS_SRC;
  1118. }
  1119. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_LO,ret_status);
  1120. //only hw handshaking need this..
  1121. switch(dma_trans_desc->fc_mode){
  1122. case DMA_M2M:
  1123. break;
  1124. case DMA_M2P:
  1125. //set dst per...
  1126. RT_ASSERT(dma_trans_desc->dst_per < DMA_HW_HS_END);
  1127. ret_status = dw_readl(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  1128. //clear 43 ~ 46 bit
  1129. ret_status &= ~0x7800;
  1130. ret_status |= DWC_CFGH_DST_PER(dma_trans_desc->dst_per);
  1131. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  1132. //DWC_CFGH_SRC_PER
  1133. break;
  1134. case DMA_P2M:
  1135. //set src per...
  1136. RT_ASSERT(dma_trans_desc->src_per < DMA_HW_HS_END);
  1137. ret_status = dw_readl(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  1138. //clear 39 ~ 42 bit
  1139. ret_status &= ~0x780;
  1140. ret_status |= DWC_CFGH_SRC_PER(dma_trans_desc->src_per);
  1141. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  1142. break;
  1143. case DMA_P2P:
  1144. //set src and dst..
  1145. RT_ASSERT(dma_trans_desc->dst_per < DMA_HW_HS_END);
  1146. RT_ASSERT(dma_trans_desc->src_per < DMA_HW_HS_END);
  1147. ret_status = dw_readl(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI);
  1148. ret_status &= ~0x7800;
  1149. ret_status &= ~0x780;
  1150. ret_status |= DWC_CFGH_SRC_PER(dma_trans_desc->src_per) | DWC_CFGH_DST_PER(dma_trans_desc->dst_per);
  1151. dw_writel(dwc,CHAN[dma_trans_desc->channel_number].CFG_HI,ret_status);
  1152. break;
  1153. default:
  1154. break;
  1155. }
  1156. dma_trans_desc->dma_controller->dma_channel[dma_trans_desc->channel_number].channel_status = CHANNEL_STATUS_BUSY;
  1157. if(dma_trans_desc->prepare_callback){
  1158. dma_trans_desc->prepare_callback(dma_trans_desc->prepare_para);
  1159. }
  1160. }
  1161. static void rt_fh_dma_cyclic_free(struct dma_transfer *p){
  1162. struct fh81_dma *my_own = p->dma_controller;
  1163. struct dw_dma *dwc;
  1164. dwc = &my_own->dwc;
  1165. volatile uint32_t ret_status;
  1166. struct dw_lli *p_lli = RT_NULL;
  1167. p_lli = p->first_lli;
  1168. //close channel first..
  1169. channel_clear_bit(dwc, CH_EN, 1<<(p->channel_number));
  1170. //check if close really
  1171. while (dw_readl(dwc, CH_EN) & 1<<(p->channel_number));
  1172. dw_writel(dwc, CLEAR.XFER, 1<<(p->channel_number));
  1173. dw_writel(dwc, CLEAR.BLOCK, 1<<(p->channel_number));
  1174. dw_writel(dwc, CLEAR.ERROR, 1<<(p->channel_number));
  1175. //rt_free(p->first_lli);
  1176. put_desc(my_own,p);
  1177. }
  1178. void rt_fh_dma_init(void){
  1179. fh81_dma_register(&fh81_dma_controller[0],"fh81_dma");
  1180. }