jazzdma.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. /*
  2. * Mips Jazz DMA controller support
  3. * Copyright (C) 1995, 1996 by Andreas Busse
  4. *
  5. * NOTE: Some of the argument checking could be removed when
  6. * things have settled down. Also, instead of returning 0xffffffff
  7. * on failure of vdma_alloc() one could leave page #0 unused
  8. * and return the more usual NULL pointer as logical address.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/module.h>
  13. #include <linux/errno.h>
  14. #include <linux/mm.h>
  15. #include <linux/bootmem.h>
  16. #include <linux/spinlock.h>
  17. #include <linux/gfp.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/jazz.h>
  20. #include <asm/io.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/dma.h>
  23. #include <asm/jazzdma.h>
  24. #include <asm/pgtable.h>
  25. /*
  26. * Set this to one to enable additional vdma debug code.
  27. */
  28. #define CONF_DEBUG_VDMA 0
  29. static VDMA_PGTBL_ENTRY *pgtbl;
  30. static DEFINE_SPINLOCK(vdma_lock);
  31. /*
  32. * Debug stuff
  33. */
  34. #define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0)
  35. static int debuglvl = 3;
  36. /*
  37. * Initialize the pagetable with a one-to-one mapping of
  38. * the first 16 Mbytes of main memory and declare all
  39. * entries to be unused. Using this method will at least
  40. * allow some early device driver operations to work.
  41. */
  42. static inline void vdma_pgtbl_init(void)
  43. {
  44. unsigned long paddr = 0;
  45. int i;
  46. for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
  47. pgtbl[i].frame = paddr;
  48. pgtbl[i].owner = VDMA_PAGE_EMPTY;
  49. paddr += VDMA_PAGESIZE;
  50. }
  51. }
  52. /*
  53. * Initialize the Jazz R4030 dma controller
  54. */
  55. static int __init vdma_init(void)
  56. {
  57. /*
  58. * Allocate 32k of memory for DMA page tables. This needs to be page
  59. * aligned and should be uncached to avoid cache flushing after every
  60. * update.
  61. */
  62. pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
  63. get_order(VDMA_PGTBL_SIZE));
  64. BUG_ON(!pgtbl);
  65. dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
  66. pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
  67. /*
  68. * Clear the R4030 translation table
  69. */
  70. vdma_pgtbl_init();
  71. r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl));
  72. r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
  73. r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
  74. printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n");
  75. return 0;
  76. }
  77. /*
  78. * Allocate DMA pagetables using a simple first-fit algorithm
  79. */
  80. unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
  81. {
  82. int first, last, pages, frame, i;
  83. unsigned long laddr, flags;
  84. /* check arguments */
  85. if (paddr > 0x1fffffff) {
  86. if (vdma_debug)
  87. printk("vdma_alloc: Invalid physical address: %08lx\n",
  88. paddr);
  89. return VDMA_ERROR; /* invalid physical address */
  90. }
  91. if (size > 0x400000 || size == 0) {
  92. if (vdma_debug)
  93. printk("vdma_alloc: Invalid size: %08lx\n", size);
  94. return VDMA_ERROR; /* invalid physical address */
  95. }
  96. spin_lock_irqsave(&vdma_lock, flags);
  97. /*
  98. * Find free chunk
  99. */
  100. pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1;
  101. first = 0;
  102. while (1) {
  103. while (pgtbl[first].owner != VDMA_PAGE_EMPTY &&
  104. first < VDMA_PGTBL_ENTRIES) first++;
  105. if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */
  106. spin_unlock_irqrestore(&vdma_lock, flags);
  107. return VDMA_ERROR;
  108. }
  109. last = first + 1;
  110. while (pgtbl[last].owner == VDMA_PAGE_EMPTY
  111. && last - first < pages)
  112. last++;
  113. if (last - first == pages)
  114. break; /* found */
  115. first = last + 1;
  116. }
  117. /*
  118. * Mark pages as allocated
  119. */
  120. laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
  121. frame = paddr & ~(VDMA_PAGESIZE - 1);
  122. for (i = first; i < last; i++) {
  123. pgtbl[i].frame = frame;
  124. pgtbl[i].owner = laddr;
  125. frame += VDMA_PAGESIZE;
  126. }
  127. /*
  128. * Update translation table and return logical start address
  129. */
  130. r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
  131. if (vdma_debug > 1)
  132. printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
  133. pages, laddr);
  134. if (vdma_debug > 2) {
  135. printk("LADDR: ");
  136. for (i = first; i < last; i++)
  137. printk("%08x ", i << 12);
  138. printk("\nPADDR: ");
  139. for (i = first; i < last; i++)
  140. printk("%08x ", pgtbl[i].frame);
  141. printk("\nOWNER: ");
  142. for (i = first; i < last; i++)
  143. printk("%08x ", pgtbl[i].owner);
  144. printk("\n");
  145. }
  146. spin_unlock_irqrestore(&vdma_lock, flags);
  147. return laddr;
  148. }
  149. EXPORT_SYMBOL(vdma_alloc);
  150. /*
  151. * Free previously allocated dma translation pages
  152. * Note that this does NOT change the translation table,
  153. * it just marks the free'd pages as unused!
  154. */
  155. int vdma_free(unsigned long laddr)
  156. {
  157. int i;
  158. i = laddr >> 12;
  159. if (pgtbl[i].owner != laddr) {
  160. printk
  161. ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
  162. laddr);
  163. return -1;
  164. }
  165. while (i < VDMA_PGTBL_ENTRIES && pgtbl[i].owner == laddr) {
  166. pgtbl[i].owner = VDMA_PAGE_EMPTY;
  167. i++;
  168. }
  169. if (vdma_debug > 1)
  170. printk("vdma_free: freed %ld pages starting from %08lx\n",
  171. i - (laddr >> 12), laddr);
  172. return 0;
  173. }
  174. EXPORT_SYMBOL(vdma_free);
  175. /*
  176. * Map certain page(s) to another physical address.
  177. * Caller must have allocated the page(s) before.
  178. */
  179. int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
  180. {
  181. int first, pages;
  182. if (laddr > 0xffffff) {
  183. if (vdma_debug)
  184. printk
  185. ("vdma_map: Invalid logical address: %08lx\n",
  186. laddr);
  187. return -EINVAL; /* invalid logical address */
  188. }
  189. if (paddr > 0x1fffffff) {
  190. if (vdma_debug)
  191. printk
  192. ("vdma_map: Invalid physical address: %08lx\n",
  193. paddr);
  194. return -EINVAL; /* invalid physical address */
  195. }
  196. pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
  197. first = laddr >> 12;
  198. if (vdma_debug)
  199. printk("vdma_remap: first=%x, pages=%x\n", first, pages);
  200. if (first + pages > VDMA_PGTBL_ENTRIES) {
  201. if (vdma_debug)
  202. printk("vdma_alloc: Invalid size: %08lx\n", size);
  203. return -EINVAL;
  204. }
  205. paddr &= ~(VDMA_PAGESIZE - 1);
  206. while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
  207. if (pgtbl[first].owner != laddr) {
  208. if (vdma_debug)
  209. printk("Trying to remap other's pages.\n");
  210. return -EPERM; /* not owner */
  211. }
  212. pgtbl[first].frame = paddr;
  213. paddr += VDMA_PAGESIZE;
  214. first++;
  215. pages--;
  216. }
  217. /*
  218. * Update translation table
  219. */
  220. r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
  221. if (vdma_debug > 2) {
  222. int i;
  223. pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
  224. first = laddr >> 12;
  225. printk("LADDR: ");
  226. for (i = first; i < first + pages; i++)
  227. printk("%08x ", i << 12);
  228. printk("\nPADDR: ");
  229. for (i = first; i < first + pages; i++)
  230. printk("%08x ", pgtbl[i].frame);
  231. printk("\nOWNER: ");
  232. for (i = first; i < first + pages; i++)
  233. printk("%08x ", pgtbl[i].owner);
  234. printk("\n");
  235. }
  236. return 0;
  237. }
  238. /*
  239. * Translate a physical address to a logical address.
  240. * This will return the logical address of the first
  241. * match.
  242. */
  243. unsigned long vdma_phys2log(unsigned long paddr)
  244. {
  245. int i;
  246. int frame;
  247. frame = paddr & ~(VDMA_PAGESIZE - 1);
  248. for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
  249. if (pgtbl[i].frame == frame)
  250. break;
  251. }
  252. if (i == VDMA_PGTBL_ENTRIES)
  253. return ~0UL;
  254. return (i << 12) + (paddr & (VDMA_PAGESIZE - 1));
  255. }
  256. EXPORT_SYMBOL(vdma_phys2log);
  257. /*
  258. * Translate a logical DMA address to a physical address
  259. */
  260. unsigned long vdma_log2phys(unsigned long laddr)
  261. {
  262. return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1));
  263. }
  264. EXPORT_SYMBOL(vdma_log2phys);
  265. /*
  266. * Print DMA statistics
  267. */
  268. void vdma_stats(void)
  269. {
  270. int i;
  271. printk("vdma_stats: CONFIG: %08x\n",
  272. r4030_read_reg32(JAZZ_R4030_CONFIG));
  273. printk("R4030 translation table base: %08x\n",
  274. r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
  275. printk("R4030 translation table limit: %08x\n",
  276. r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
  277. printk("vdma_stats: INV_ADDR: %08x\n",
  278. r4030_read_reg32(JAZZ_R4030_INV_ADDR));
  279. printk("vdma_stats: R_FAIL_ADDR: %08x\n",
  280. r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
  281. printk("vdma_stats: M_FAIL_ADDR: %08x\n",
  282. r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
  283. printk("vdma_stats: IRQ_SOURCE: %08x\n",
  284. r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
  285. printk("vdma_stats: I386_ERROR: %08x\n",
  286. r4030_read_reg32(JAZZ_R4030_I386_ERROR));
  287. printk("vdma_chnl_modes: ");
  288. for (i = 0; i < 8; i++)
  289. printk("%04x ",
  290. (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
  291. (i << 5)));
  292. printk("\n");
  293. printk("vdma_chnl_enables: ");
  294. for (i = 0; i < 8; i++)
  295. printk("%04x ",
  296. (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  297. (i << 5)));
  298. printk("\n");
  299. }
  300. /*
  301. * DMA transfer functions
  302. */
  303. /*
  304. * Enable a DMA channel. Also clear any error conditions.
  305. */
  306. void vdma_enable(int channel)
  307. {
  308. int status;
  309. if (vdma_debug)
  310. printk("vdma_enable: channel %d\n", channel);
  311. /*
  312. * Check error conditions first
  313. */
  314. status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
  315. if (status & 0x400)
  316. printk("VDMA: Channel %d: Address error!\n", channel);
  317. if (status & 0x200)
  318. printk("VDMA: Channel %d: Memory error!\n", channel);
  319. /*
  320. * Clear all interrupt flags
  321. */
  322. r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
  323. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  324. (channel << 5)) | R4030_TC_INTR
  325. | R4030_MEM_INTR | R4030_ADDR_INTR);
  326. /*
  327. * Enable the desired channel
  328. */
  329. r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
  330. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  331. (channel << 5)) |
  332. R4030_CHNL_ENABLE);
  333. }
  334. EXPORT_SYMBOL(vdma_enable);
  335. /*
  336. * Disable a DMA channel
  337. */
  338. void vdma_disable(int channel)
  339. {
  340. if (vdma_debug) {
  341. int status =
  342. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  343. (channel << 5));
  344. printk("vdma_disable: channel %d\n", channel);
  345. printk("VDMA: channel %d status: %04x (%s) mode: "
  346. "%02x addr: %06x count: %06x\n",
  347. channel, status,
  348. ((status & 0x600) ? "ERROR" : "OK"),
  349. (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
  350. (channel << 5)),
  351. (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR +
  352. (channel << 5)),
  353. (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT +
  354. (channel << 5)));
  355. }
  356. r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
  357. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  358. (channel << 5)) &
  359. ~R4030_CHNL_ENABLE);
  360. /*
  361. * After disabling a DMA channel a remote bus register should be
  362. * read to ensure that the current DMA acknowledge cycle is completed.
  363. */
  364. *((volatile unsigned int *) JAZZ_DUMMY_DEVICE);
  365. }
  366. EXPORT_SYMBOL(vdma_disable);
  367. /*
  368. * Set DMA mode. This function accepts the mode values used
  369. * to set a PC-style DMA controller. For the SCSI and FDC
  370. * channels, we also set the default modes each time we're
  371. * called.
  372. * NOTE: The FAST and BURST dma modes are supported by the
  373. * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
  374. * for now.
  375. */
  376. void vdma_set_mode(int channel, int mode)
  377. {
  378. if (vdma_debug)
  379. printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
  380. mode);
  381. switch (channel) {
  382. case JAZZ_SCSI_DMA: /* scsi */
  383. r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
  384. /* R4030_MODE_FAST | */
  385. /* R4030_MODE_BURST | */
  386. R4030_MODE_INTR_EN |
  387. R4030_MODE_WIDTH_16 |
  388. R4030_MODE_ATIME_80);
  389. break;
  390. case JAZZ_FLOPPY_DMA: /* floppy */
  391. r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
  392. /* R4030_MODE_FAST | */
  393. /* R4030_MODE_BURST | */
  394. R4030_MODE_INTR_EN |
  395. R4030_MODE_WIDTH_8 |
  396. R4030_MODE_ATIME_120);
  397. break;
  398. case JAZZ_AUDIOL_DMA:
  399. case JAZZ_AUDIOR_DMA:
  400. printk("VDMA: Audio DMA not supported yet.\n");
  401. break;
  402. default:
  403. printk
  404. ("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
  405. channel);
  406. }
  407. switch (mode) {
  408. case DMA_MODE_READ:
  409. r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
  410. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  411. (channel << 5)) &
  412. ~R4030_CHNL_WRITE);
  413. break;
  414. case DMA_MODE_WRITE:
  415. r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
  416. r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
  417. (channel << 5)) |
  418. R4030_CHNL_WRITE);
  419. break;
  420. default:
  421. printk
  422. ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",
  423. mode);
  424. }
  425. }
  426. EXPORT_SYMBOL(vdma_set_mode);
  427. /*
  428. * Set Transfer Address
  429. */
  430. void vdma_set_addr(int channel, long addr)
  431. {
  432. if (vdma_debug)
  433. printk("vdma_set_addr: channel %d, addr %lx\n", channel,
  434. addr);
  435. r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr);
  436. }
  437. EXPORT_SYMBOL(vdma_set_addr);
  438. /*
  439. * Set Transfer Count
  440. */
  441. void vdma_set_count(int channel, int count)
  442. {
  443. if (vdma_debug)
  444. printk("vdma_set_count: channel %d, count %08x\n", channel,
  445. (unsigned) count);
  446. r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count);
  447. }
  448. EXPORT_SYMBOL(vdma_set_count);
  449. /*
  450. * Get Residual
  451. */
  452. int vdma_get_residue(int channel)
  453. {
  454. int residual;
  455. residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5));
  456. if (vdma_debug)
  457. printk("vdma_get_residual: channel %d: residual=%d\n",
  458. channel, residual);
  459. return residual;
  460. }
  461. /*
  462. * Get DMA channel enable register
  463. */
  464. int vdma_get_enable(int channel)
  465. {
  466. int enable;
  467. enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
  468. if (vdma_debug)
  469. printk("vdma_get_enable: channel %d: enable=%d\n", channel,
  470. enable);
  471. return enable;
  472. }
  473. arch_initcall(vdma_init);