// SPDX-License-Identifier: GPL-2.0 /* * Mips Jazz DMA controller support * Copyright (C) 1995, 1996 by Andreas Busse * * NOTE: Some of the argument checking could be removed when * things have settled down. Also, instead of returning 0xffffffff * on failure of vdma_alloc() one could leave page #0 unused * and return the more usual NULL pointer as logical address.
*/ #include <linux/kernel.h> #include <linux/init.h> #include <linux/export.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/memblock.h> #include <linux/spinlock.h> #include <linux/gfp.h> #include <linux/dma-map-ops.h> #include <asm/mipsregs.h> #include <asm/jazz.h> #include <asm/io.h> #include <linux/uaccess.h> #include <asm/dma.h> #include <asm/jazzdma.h>
/* * Set this to one to enable additional vdma debug code.
*/ #define CONF_DEBUG_VDMA 0
/* * Initialize the pagetable with a one-to-one mapping of * the first 16 Mbytes of main memory and declare all * entries to be unused. Using this method will at least * allow some early device driver operations to work.
*/ staticinlinevoid vdma_pgtbl_init(void)
{ unsignedlong paddr = 0; int i;
for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
pgtbl[i].frame = paddr;
pgtbl[i].owner = VDMA_PAGE_EMPTY;
paddr += VDMA_PAGESIZE;
}
}
/* * Initialize the Jazz R4030 dma controller
*/ staticint __init vdma_init(void)
{ /* * Allocate 32k of memory for DMA page tables. This needs to be page * aligned and should be uncached to avoid cache flushing after every * update.
*/
pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
get_order(VDMA_PGTBL_SIZE));
BUG_ON(!pgtbl);
dma_cache_wback_inv((unsignedlong)pgtbl, VDMA_PGTBL_SIZE);
pgtbl = (VDMA_PGTBL_ENTRY *)CKSEG1ADDR((unsignedlong)pgtbl);
/* * Clear the R4030 translation table
*/
vdma_pgtbl_init();
if (vdma_debug > 1)
printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
pages, laddr);
if (vdma_debug > 2) {
printk("LADDR: "); for (i = first; i < last; i++)
printk("%08x ", i << 12);
printk("\nPADDR: "); for (i = first; i < last; i++)
printk("%08x ", pgtbl[i].frame);
printk("\nOWNER: "); for (i = first; i < last; i++)
printk("%08x ", pgtbl[i].owner);
printk("\n");
}
spin_unlock_irqrestore(&vdma_lock, flags);
return laddr;
}
EXPORT_SYMBOL(vdma_alloc);
/* * Free previously allocated dma translation pages * Note that this does NOT change the translation table, * it just marks the free'd pages as unused!
*/ int vdma_free(unsignedlong laddr)
{ int i;
i = laddr >> 12;
if (pgtbl[i].owner != laddr) {
printk
("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
laddr); return -1;
}
while (i < VDMA_PGTBL_ENTRIES && pgtbl[i].owner == laddr) {
pgtbl[i].owner = VDMA_PAGE_EMPTY;
i++;
}
if (vdma_debug > 1)
printk("vdma_free: freed %ld pages starting from %08lx\n",
i - (laddr >> 12), laddr);
return 0;
}
EXPORT_SYMBOL(vdma_free);
/* * Translate a physical address to a logical address. * This will return the logical address of the first * match.
*/ unsignedlong vdma_phys2log(unsignedlong paddr)
{ int i; int frame;
frame = paddr & ~(VDMA_PAGESIZE - 1);
for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) { if (pgtbl[i].frame == frame) break;
}
/* * After disabling a DMA channel a remote bus register should be * read to ensure that the current DMA acknowledge cycle is completed.
*/
*((volatileunsignedint *) JAZZ_DUMMY_DEVICE);
}
EXPORT_SYMBOL(vdma_disable);
/* * Set DMA mode. This function accepts the mode values used * to set a PC-style DMA controller. For the SCSI and FDC * channels, we also set the default modes each time we're * called. * NOTE: The FAST and BURST dma modes are supported by the * R4030 Rev. 2 and PICA chipsets only. I leave them disabled * for now.
*/ void vdma_set_mode(int channel, int mode)
{ if (vdma_debug)
printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
mode);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.