dma.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /* dma.c: DMA controller management on FR401 and the like
  2. *
  3. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <linux/module.h>
  12. #include <linux/sched.h>
  13. #include <linux/spinlock.h>
  14. #include <linux/errno.h>
  15. #include <linux/init.h>
  16. #include <asm/dma.h>
  17. #include <asm/gpio-regs.h>
  18. #include <asm/irc-regs.h>
  19. #include <asm/cpu-irqs.h>
  20. struct frv_dma_channel {
  21. uint8_t flags;
  22. #define FRV_DMA_FLAGS_RESERVED 0x01
  23. #define FRV_DMA_FLAGS_INUSE 0x02
  24. #define FRV_DMA_FLAGS_PAUSED 0x04
  25. uint8_t cap; /* capabilities available */
  26. int irq; /* completion IRQ */
  27. uint32_t dreqbit;
  28. uint32_t dackbit;
  29. uint32_t donebit;
  30. const unsigned long ioaddr; /* DMA controller regs addr */
  31. const char *devname;
  32. dma_irq_handler_t handler;
  33. void *data;
  34. };
  35. #define __get_DMAC(IO,X) ({ *(volatile unsigned long *)((IO) + DMAC_##X##x); })
  36. #define __set_DMAC(IO,X,V) \
  37. do { \
  38. *(volatile unsigned long *)((IO) + DMAC_##X##x) = (V); \
  39. mb(); \
  40. } while(0)
  41. #define ___set_DMAC(IO,X,V) \
  42. do { \
  43. *(volatile unsigned long *)((IO) + DMAC_##X##x) = (V); \
  44. } while(0)
  45. static struct frv_dma_channel frv_dma_channels[FRV_DMA_NCHANS] = {
  46. [0] = {
  47. .cap = FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
  48. .irq = IRQ_CPU_DMA0,
  49. .dreqbit = SIR_DREQ0_INPUT,
  50. .dackbit = SOR_DACK0_OUTPUT,
  51. .donebit = SOR_DONE0_OUTPUT,
  52. .ioaddr = 0xfe000900,
  53. },
  54. [1] = {
  55. .cap = FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK | FRV_DMA_CAP_DONE,
  56. .irq = IRQ_CPU_DMA1,
  57. .dreqbit = SIR_DREQ1_INPUT,
  58. .dackbit = SOR_DACK1_OUTPUT,
  59. .donebit = SOR_DONE1_OUTPUT,
  60. .ioaddr = 0xfe000980,
  61. },
  62. [2] = {
  63. .cap = FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
  64. .irq = IRQ_CPU_DMA2,
  65. .dreqbit = SIR_DREQ2_INPUT,
  66. .dackbit = SOR_DACK2_OUTPUT,
  67. .ioaddr = 0xfe000a00,
  68. },
  69. [3] = {
  70. .cap = FRV_DMA_CAP_DREQ | FRV_DMA_CAP_DACK,
  71. .irq = IRQ_CPU_DMA3,
  72. .dreqbit = SIR_DREQ3_INPUT,
  73. .dackbit = SOR_DACK3_OUTPUT,
  74. .ioaddr = 0xfe000a80,
  75. },
  76. [4] = {
  77. .cap = FRV_DMA_CAP_DREQ,
  78. .irq = IRQ_CPU_DMA4,
  79. .dreqbit = SIR_DREQ4_INPUT,
  80. .ioaddr = 0xfe001000,
  81. },
  82. [5] = {
  83. .cap = FRV_DMA_CAP_DREQ,
  84. .irq = IRQ_CPU_DMA5,
  85. .dreqbit = SIR_DREQ5_INPUT,
  86. .ioaddr = 0xfe001080,
  87. },
  88. [6] = {
  89. .cap = FRV_DMA_CAP_DREQ,
  90. .irq = IRQ_CPU_DMA6,
  91. .dreqbit = SIR_DREQ6_INPUT,
  92. .ioaddr = 0xfe001100,
  93. },
  94. [7] = {
  95. .cap = FRV_DMA_CAP_DREQ,
  96. .irq = IRQ_CPU_DMA7,
  97. .dreqbit = SIR_DREQ7_INPUT,
  98. .ioaddr = 0xfe001180,
  99. },
  100. };
  101. static DEFINE_RWLOCK(frv_dma_channels_lock);
  102. unsigned long frv_dma_inprogress;
  103. #define frv_clear_dma_inprogress(channel) \
  104. atomic_clear_mask(1 << (channel), &frv_dma_inprogress);
  105. #define frv_set_dma_inprogress(channel) \
  106. atomic_set_mask(1 << (channel), &frv_dma_inprogress);
  107. /*****************************************************************************/
  108. /*
  109. * DMA irq handler - determine channel involved, grab status and call real handler
  110. */
  111. static irqreturn_t dma_irq_handler(int irq, void *_channel)
  112. {
  113. struct frv_dma_channel *channel = _channel;
  114. frv_clear_dma_inprogress(channel - frv_dma_channels);
  115. return channel->handler(channel - frv_dma_channels,
  116. __get_DMAC(channel->ioaddr, CSTR),
  117. channel->data);
  118. } /* end dma_irq_handler() */
  119. /*****************************************************************************/
  120. /*
  121. * Determine which DMA controllers are present on this CPU
  122. */
  123. void __init frv_dma_init(void)
  124. {
  125. unsigned long psr = __get_PSR();
  126. int num_dma, i;
  127. /* First, determine how many DMA channels are available */
  128. switch (PSR_IMPLE(psr)) {
  129. case PSR_IMPLE_FR405:
  130. case PSR_IMPLE_FR451:
  131. case PSR_IMPLE_FR501:
  132. case PSR_IMPLE_FR551:
  133. num_dma = FRV_DMA_8CHANS;
  134. break;
  135. case PSR_IMPLE_FR401:
  136. default:
  137. num_dma = FRV_DMA_4CHANS;
  138. break;
  139. }
  140. /* Now mark all of the non-existent channels as reserved */
  141. for(i = num_dma; i < FRV_DMA_NCHANS; i++)
  142. frv_dma_channels[i].flags = FRV_DMA_FLAGS_RESERVED;
  143. } /* end frv_dma_init() */
  144. /*****************************************************************************/
  145. /*
  146. * allocate a DMA controller channel and the IRQ associated with it
  147. */
  148. int frv_dma_open(const char *devname,
  149. unsigned long dmamask,
  150. int dmacap,
  151. dma_irq_handler_t handler,
  152. unsigned long irq_flags,
  153. void *data)
  154. {
  155. struct frv_dma_channel *channel;
  156. int dma, ret;
  157. uint32_t val;
  158. write_lock(&frv_dma_channels_lock);
  159. ret = -ENOSPC;
  160. for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
  161. channel = &frv_dma_channels[dma];
  162. if (!test_bit(dma, &dmamask))
  163. continue;
  164. if ((channel->cap & dmacap) != dmacap)
  165. continue;
  166. if (!frv_dma_channels[dma].flags)
  167. goto found;
  168. }
  169. goto out;
  170. found:
  171. ret = request_irq(channel->irq, dma_irq_handler, irq_flags, devname, channel);
  172. if (ret < 0)
  173. goto out;
  174. /* okay, we've allocated all the resources */
  175. channel = &frv_dma_channels[dma];
  176. channel->flags |= FRV_DMA_FLAGS_INUSE;
  177. channel->devname = devname;
  178. channel->handler = handler;
  179. channel->data = data;
  180. /* Now make sure we are set up for DMA and not GPIO */
  181. /* SIR bit must be set for DMA to work */
  182. __set_SIR(channel->dreqbit | __get_SIR());
  183. /* SOR bits depend on what the caller requests */
  184. val = __get_SOR();
  185. if(dmacap & FRV_DMA_CAP_DACK)
  186. val |= channel->dackbit;
  187. else
  188. val &= ~channel->dackbit;
  189. if(dmacap & FRV_DMA_CAP_DONE)
  190. val |= channel->donebit;
  191. else
  192. val &= ~channel->donebit;
  193. __set_SOR(val);
  194. ret = dma;
  195. out:
  196. write_unlock(&frv_dma_channels_lock);
  197. return ret;
  198. } /* end frv_dma_open() */
  199. EXPORT_SYMBOL(frv_dma_open);
  200. /*****************************************************************************/
  201. /*
  202. * close a DMA channel and its associated interrupt
  203. */
  204. void frv_dma_close(int dma)
  205. {
  206. struct frv_dma_channel *channel = &frv_dma_channels[dma];
  207. unsigned long flags;
  208. write_lock_irqsave(&frv_dma_channels_lock, flags);
  209. free_irq(channel->irq, channel);
  210. frv_dma_stop(dma);
  211. channel->flags &= ~FRV_DMA_FLAGS_INUSE;
  212. write_unlock_irqrestore(&frv_dma_channels_lock, flags);
  213. } /* end frv_dma_close() */
  214. EXPORT_SYMBOL(frv_dma_close);
  215. /*****************************************************************************/
  216. /*
  217. * set static configuration on a DMA channel
  218. */
  219. void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr)
  220. {
  221. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  222. ___set_DMAC(ioaddr, CCFR, ccfr);
  223. ___set_DMAC(ioaddr, CCTR, cctr);
  224. ___set_DMAC(ioaddr, APR, apr);
  225. mb();
  226. } /* end frv_dma_config() */
  227. EXPORT_SYMBOL(frv_dma_config);
  228. /*****************************************************************************/
  229. /*
  230. * start a DMA channel
  231. */
  232. void frv_dma_start(int dma,
  233. unsigned long sba, unsigned long dba,
  234. unsigned long pix, unsigned long six, unsigned long bcl)
  235. {
  236. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  237. ___set_DMAC(ioaddr, SBA, sba);
  238. ___set_DMAC(ioaddr, DBA, dba);
  239. ___set_DMAC(ioaddr, PIX, pix);
  240. ___set_DMAC(ioaddr, SIX, six);
  241. ___set_DMAC(ioaddr, BCL, bcl);
  242. ___set_DMAC(ioaddr, CSTR, 0);
  243. mb();
  244. __set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
  245. frv_set_dma_inprogress(dma);
  246. } /* end frv_dma_start() */
  247. EXPORT_SYMBOL(frv_dma_start);
  248. /*****************************************************************************/
  249. /*
  250. * restart a DMA channel that's been stopped in circular addressing mode by comparison-end
  251. */
  252. void frv_dma_restart_circular(int dma, unsigned long six)
  253. {
  254. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  255. ___set_DMAC(ioaddr, SIX, six);
  256. ___set_DMAC(ioaddr, CSTR, __get_DMAC(ioaddr, CSTR) & ~DMAC_CSTRx_CE);
  257. mb();
  258. __set_DMAC(ioaddr, CCTR, __get_DMAC(ioaddr, CCTR) | DMAC_CCTRx_ACT);
  259. frv_set_dma_inprogress(dma);
  260. } /* end frv_dma_restart_circular() */
  261. EXPORT_SYMBOL(frv_dma_restart_circular);
  262. /*****************************************************************************/
  263. /*
  264. * stop a DMA channel
  265. */
  266. void frv_dma_stop(int dma)
  267. {
  268. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  269. uint32_t cctr;
  270. ___set_DMAC(ioaddr, CSTR, 0);
  271. cctr = __get_DMAC(ioaddr, CCTR);
  272. cctr &= ~(DMAC_CCTRx_IE | DMAC_CCTRx_ACT);
  273. cctr |= DMAC_CCTRx_FC; /* fifo clear */
  274. __set_DMAC(ioaddr, CCTR, cctr);
  275. __set_DMAC(ioaddr, BCL, 0);
  276. frv_clear_dma_inprogress(dma);
  277. } /* end frv_dma_stop() */
  278. EXPORT_SYMBOL(frv_dma_stop);
  279. /*****************************************************************************/
  280. /*
  281. * test interrupt status of DMA channel
  282. */
  283. int is_frv_dma_interrupting(int dma)
  284. {
  285. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  286. return __get_DMAC(ioaddr, CSTR) & (1 << 23);
  287. } /* end is_frv_dma_interrupting() */
  288. EXPORT_SYMBOL(is_frv_dma_interrupting);
  289. /*****************************************************************************/
  290. /*
  291. * dump data about a DMA channel
  292. */
  293. void frv_dma_dump(int dma)
  294. {
  295. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  296. unsigned long cstr, pix, six, bcl;
  297. cstr = __get_DMAC(ioaddr, CSTR);
  298. pix = __get_DMAC(ioaddr, PIX);
  299. six = __get_DMAC(ioaddr, SIX);
  300. bcl = __get_DMAC(ioaddr, BCL);
  301. printk("DMA[%d] cstr=%lx pix=%lx six=%lx bcl=%lx\n", dma, cstr, pix, six, bcl);
  302. } /* end frv_dma_dump() */
  303. EXPORT_SYMBOL(frv_dma_dump);
  304. /*****************************************************************************/
  305. /*
  306. * pause all DMA controllers
  307. * - called by clock mangling routines
  308. * - caller must be holding interrupts disabled
  309. */
  310. void frv_dma_pause_all(void)
  311. {
  312. struct frv_dma_channel *channel;
  313. unsigned long ioaddr;
  314. unsigned long cstr, cctr;
  315. int dma;
  316. write_lock(&frv_dma_channels_lock);
  317. for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
  318. channel = &frv_dma_channels[dma];
  319. if (!(channel->flags & FRV_DMA_FLAGS_INUSE))
  320. continue;
  321. ioaddr = channel->ioaddr;
  322. cctr = __get_DMAC(ioaddr, CCTR);
  323. if (cctr & DMAC_CCTRx_ACT) {
  324. cctr &= ~DMAC_CCTRx_ACT;
  325. __set_DMAC(ioaddr, CCTR, cctr);
  326. do {
  327. cstr = __get_DMAC(ioaddr, CSTR);
  328. } while (cstr & DMAC_CSTRx_BUSY);
  329. if (cstr & DMAC_CSTRx_FED)
  330. channel->flags |= FRV_DMA_FLAGS_PAUSED;
  331. frv_clear_dma_inprogress(dma);
  332. }
  333. }
  334. } /* end frv_dma_pause_all() */
  335. EXPORT_SYMBOL(frv_dma_pause_all);
  336. /*****************************************************************************/
  337. /*
  338. * resume paused DMA controllers
  339. * - called by clock mangling routines
  340. * - caller must be holding interrupts disabled
  341. */
  342. void frv_dma_resume_all(void)
  343. {
  344. struct frv_dma_channel *channel;
  345. unsigned long ioaddr;
  346. unsigned long cstr, cctr;
  347. int dma;
  348. for (dma = FRV_DMA_NCHANS - 1; dma >= 0; dma--) {
  349. channel = &frv_dma_channels[dma];
  350. if (!(channel->flags & FRV_DMA_FLAGS_PAUSED))
  351. continue;
  352. ioaddr = channel->ioaddr;
  353. cstr = __get_DMAC(ioaddr, CSTR);
  354. cstr &= ~(DMAC_CSTRx_FED | DMAC_CSTRx_INT);
  355. __set_DMAC(ioaddr, CSTR, cstr);
  356. cctr = __get_DMAC(ioaddr, CCTR);
  357. cctr |= DMAC_CCTRx_ACT;
  358. __set_DMAC(ioaddr, CCTR, cctr);
  359. channel->flags &= ~FRV_DMA_FLAGS_PAUSED;
  360. frv_set_dma_inprogress(dma);
  361. }
  362. write_unlock(&frv_dma_channels_lock);
  363. } /* end frv_dma_resume_all() */
  364. EXPORT_SYMBOL(frv_dma_resume_all);
  365. /*****************************************************************************/
  366. /*
  367. * dma status clear
  368. */
  369. void frv_dma_status_clear(int dma)
  370. {
  371. unsigned long ioaddr = frv_dma_channels[dma].ioaddr;
  372. uint32_t cctr;
  373. ___set_DMAC(ioaddr, CSTR, 0);
  374. cctr = __get_DMAC(ioaddr, CCTR);
  375. } /* end frv_dma_status_clear() */
  376. EXPORT_SYMBOL(frv_dma_status_clear);