jazzdma.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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 <asm/mipsregs.h>
  18. #include <asm/jazz.h>
  19. #include <asm/io.h>
  20. #include <asm/uaccess.h>
  21. #include <asm/dma.h>
  22. #include <asm/jazzdma.h>
  23. #include <asm/pgtable.h>
  24. /*
  25. * Set this to one to enable additional vdma debug code.
  26. */
  27. #define CONF_DEBUG_VDMA 0
  28. static VDMA_PGTBL_ENTRY *pgtbl;
  29. static DEFINE_SPINLOCK(vdma_lock);
  30. /*
  31. * Debug stuff
  32. */
  33. #define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0)
  34. static int debuglvl = 3;
  35. /*
  36. * Initialize the pagetable with a one-to-one mapping of
  37. * the first 16 Mbytes of main memory and declare all
  38. * entries to be unused. Using this method will at least
  39. * allow some early device driver operations to work.
  40. */
  41. static inline void vdma_pgtbl_init(void)
  42. {
  43. unsigned long paddr = 0;
  44. int i;
  45. for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
  46. pgtbl[i].frame = paddr;
  47. pgtbl[i].owner = VDMA_PAGE_EMPTY;
  48. paddr += VDMA_PAGESIZE;
  49. }
  50. }
  51. /*
  52. * Initialize the Jazz R4030 dma controller
  53. */
  54. static int __init vdma_init(void)
  55. {
  56. /*
  57. * Allocate 32k of memory for DMA page tables. This needs to be page
  58. * aligned and should be uncached to avoid cache flushing after every
  59. * update.
  60. */
  61. pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
  62. get_order(VDMA_PGTBL_SIZE));
  63. BUG_ON(!pgtbl);
  64. dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
  65. pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
  66. /*
  67. * Clear the R4030 translation table
  68. */
  69. vdma_pgtbl_init();
  70. r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl));
  71. r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
  72. r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
  73. printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n");
  74. return 0;
  75. }
  76. /*
  77. * Allocate DMA pagetables using a simple first-fit algorithm
  78. */
  79. unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
  80. {
  81. int first, last, pages, frame, i;
  82. unsigned long laddr, flags;
  83. /* check arguments */
  84. if (paddr > 0x1fffffff) {
  85. if (vdma_debug)
  86. printk("vdma_alloc: Invalid physical address: %08lx\n",
  87. paddr);
  88. return VDMA_ERROR; /* invalid physical address */
  89. }
  90. if (size > 0x400000 || size == 0) {
  91. if (vdma_debug)
  92. printk("vdma_alloc: Invalid size: %08lx\n", size);
  93. return VDMA_ERROR; /* invalid physical address */
  94. }
  95. spin_lock_irqsave(&vdma_lock, flags);
  96. /*
  97. * Find free chunk
  98. */
  99. pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1;
  100. first = 0;
  101. while (1) {
  102. while (pgtbl[first].owner != VDMA_PAGE_EMPTY &&
  103. first < VDMA_PGTBL_ENTRIES) first++;
  104. if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */
  105. spin_unlock_irqrestore(&vdma_lock, flags);
  106. return VDMA_ERROR;
  107. }
  108. last = first + 1;
  109. while (pgtbl[last].owner == VDMA_PAGE_EMPTY
  110. && last - first < pages)
  111. last++;
  112. if (last - first == pages)
  113. break; /* found */
  114. first = last + 1;
  115. }
  116. /*
  117. * Mark pages as allocated
  118. */
  119. laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
  120. frame = paddr & ~(VDMA_PAGESIZE - 1);
  121. for (i = first; i < last; i++) {
  122. pgtbl[i].frame = frame;
  123. pgtbl[i].owner = laddr;
  124. frame += VDMA_PAGESIZE;
  125. }
  126. /*
  127. * Update translation table and return logical start address
  128. */
  129. r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
  130. if (vdma_debug > 1)
  131. printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
  132. pages, laddr);
  133. if (vdma_debug > 2) {
  134. printk("LADDR: ");
  135. for (i = first; i < last; i++)
  136. printk("%08x ", i << 12);
  137. printk("\nPADDR: ");
  138. for (i = first; i < last; i++)
  139. printk("%08x ", pgtbl[i].frame);
  140. printk("\nOWNER: ");
  141. for (i = first; i < last; i++)
  142. printk("%08x ", pgtbl[i].owner);
  143. printk("\n");
  144. }
  145. spin_unlock_irqrestore(&vdma_lock, flags);
  146. return laddr;
  147. }
  148. EXPORT_SYMBOL(vdma_alloc);
  149. /*
  150. * Free previously allocated dma translation pages
  151. * Note that this does NOT change the translation table,
  152. * it just marks the free'd pages as unused!
  153. */
  154. int vdma_free(unsigned long laddr)
  155. {
  156. int i;
  157. i = laddr >> 12;
  158. if (pgtbl[i].owner != laddr) {
  159. printk
  160. ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
  161. laddr);
  162. return -1;
  163. }
  164. while (pgtbl[i].owner == laddr && i < VDMA_PGTBL_ENTRIES) {
  165. pgtbl[i].owner = VDMA_PAGE_EMPTY;
  166. i++;
  167. }
  168. if (vdma_debug > 1)
  169. printk("vdma_free: freed %ld pages starting from %08lx\n",
  170. i - (laddr >> 12), laddr);
  171. return 0;
  172. }
  173. EXPORT_SYMBOL(vdma_free);
  174. /*
  175. * Map certain page(s) to another physical address.
  176. * Caller must have allocated the page(s) before.
  177. */
  178. int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
  179. {
  180. int first, pages, npages;
  181. if (laddr > 0xffffff) {
  182. if (vdma_debug)
  183. printk
  184. ("vdma_map: Invalid logical address: %08lx\n",
  185. laddr);
  186. return -EINVAL; /* invalid logical address */
  187. }
  188. if (paddr > 0x1fffffff) {
  189. if (vdma_debug)
  190. printk
  191. ("vdma_map: Invalid physical address: %08lx\n",
  192. paddr);
  193. return -EINVAL; /* invalid physical address */
  194. }
  195. npages = pages =
  196. (((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);