diff options
Diffstat (limited to 'arch/mips/jazz/jazzdma.c')
-rw-r--r-- | arch/mips/jazz/jazzdma.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index e8e0ffb9354d..c672c08d49e5 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | #define CONF_DEBUG_VDMA 0 | 28 | #define CONF_DEBUG_VDMA 0 |
29 | 29 | ||
30 | static unsigned long vdma_pagetable_start; | 30 | static VDMA_PGTBL_ENTRY *pgtbl; |
31 | 31 | ||
32 | static DEFINE_SPINLOCK(vdma_lock); | 32 | static DEFINE_SPINLOCK(vdma_lock); |
33 | 33 | ||
@@ -46,7 +46,6 @@ static int debuglvl = 3; | |||
46 | */ | 46 | */ |
47 | static inline void vdma_pgtbl_init(void) | 47 | static inline void vdma_pgtbl_init(void) |
48 | { | 48 | { |
49 | VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
50 | unsigned long paddr = 0; | 49 | unsigned long paddr = 0; |
51 | int i; | 50 | int i; |
52 | 51 | ||
@@ -60,31 +59,31 @@ static inline void vdma_pgtbl_init(void) | |||
60 | /* | 59 | /* |
61 | * Initialize the Jazz R4030 dma controller | 60 | * Initialize the Jazz R4030 dma controller |
62 | */ | 61 | */ |
63 | void __init vdma_init(void) | 62 | static int __init vdma_init(void) |
64 | { | 63 | { |
65 | /* | 64 | /* |
66 | * Allocate 32k of memory for DMA page tables. This needs to be page | 65 | * Allocate 32k of memory for DMA page tables. This needs to be page |
67 | * aligned and should be uncached to avoid cache flushing after every | 66 | * aligned and should be uncached to avoid cache flushing after every |
68 | * update. | 67 | * update. |
69 | */ | 68 | */ |
70 | vdma_pagetable_start = | 69 | pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA, |
71 | (unsigned long) alloc_bootmem_low_pages(VDMA_PGTBL_SIZE); | 70 | get_order(VDMA_PGTBL_SIZE)); |
72 | if (!vdma_pagetable_start) | 71 | if (!pgtbl) |
73 | BUG(); | 72 | BUG(); |
74 | dma_cache_wback_inv(vdma_pagetable_start, VDMA_PGTBL_SIZE); | 73 | dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE); |
75 | vdma_pagetable_start = KSEG1ADDR(vdma_pagetable_start); | 74 | pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl); |
76 | 75 | ||
77 | /* | 76 | /* |
78 | * Clear the R4030 translation table | 77 | * Clear the R4030 translation table |
79 | */ | 78 | */ |
80 | vdma_pgtbl_init(); | 79 | vdma_pgtbl_init(); |
81 | 80 | ||
82 | r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, | 81 | r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl)); |
83 | CPHYSADDR(vdma_pagetable_start)); | ||
84 | r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE); | 82 | r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE); |
85 | r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); | 83 | r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); |
86 | 84 | ||
87 | printk("VDMA: R4030 DMA pagetables initialized.\n"); | 85 | printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n"); |
86 | return 0; | ||
88 | } | 87 | } |
89 | 88 | ||
90 | /* | 89 | /* |
@@ -92,7 +91,6 @@ void __init vdma_init(void) | |||
92 | */ | 91 | */ |
93 | unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | 92 | unsigned long vdma_alloc(unsigned long paddr, unsigned long size) |
94 | { | 93 | { |
95 | VDMA_PGTBL_ENTRY *entry = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
96 | int first, last, pages, frame, i; | 94 | int first, last, pages, frame, i; |
97 | unsigned long laddr, flags; | 95 | unsigned long laddr, flags; |
98 | 96 | ||
@@ -114,10 +112,10 @@ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | |||
114 | /* | 112 | /* |
115 | * Find free chunk | 113 | * Find free chunk |
116 | */ | 114 | */ |
117 | pages = (size + 4095) >> 12; /* no. of pages to allocate */ | 115 | pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1; |
118 | first = 0; | 116 | first = 0; |
119 | while (1) { | 117 | while (1) { |
120 | while (entry[first].owner != VDMA_PAGE_EMPTY && | 118 | while (pgtbl[first].owner != VDMA_PAGE_EMPTY && |
121 | first < VDMA_PGTBL_ENTRIES) first++; | 119 | first < VDMA_PGTBL_ENTRIES) first++; |
122 | if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */ | 120 | if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */ |
123 | spin_unlock_irqrestore(&vdma_lock, flags); | 121 | spin_unlock_irqrestore(&vdma_lock, flags); |
@@ -125,12 +123,13 @@ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | |||
125 | } | 123 | } |
126 | 124 | ||
127 | last = first + 1; | 125 | last = first + 1; |
128 | while (entry[last].owner == VDMA_PAGE_EMPTY | 126 | while (pgtbl[last].owner == VDMA_PAGE_EMPTY |
129 | && last - first < pages) | 127 | && last - first < pages) |
130 | last++; | 128 | last++; |
131 | 129 | ||
132 | if (last - first == pages) | 130 | if (last - first == pages) |
133 | break; /* found */ | 131 | break; /* found */ |
132 | first = last + 1; | ||
134 | } | 133 | } |
135 | 134 | ||
136 | /* | 135 | /* |
@@ -140,8 +139,8 @@ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | |||
140 | frame = paddr & ~(VDMA_PAGESIZE - 1); | 139 | frame = paddr & ~(VDMA_PAGESIZE - 1); |
141 | 140 | ||
142 | for (i = first; i < last; i++) { | 141 | for (i = first; i < last; i++) { |
143 | entry[i].frame = frame; | 142 | pgtbl[i].frame = frame; |
144 | entry[i].owner = laddr; | 143 | pgtbl[i].owner = laddr; |
145 | frame += VDMA_PAGESIZE; | 144 | frame += VDMA_PAGESIZE; |
146 | } | 145 | } |
147 | 146 | ||
@@ -160,10 +159,10 @@ unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | |||
160 | printk("%08x ", i << 12); | 159 | printk("%08x ", i << 12); |
161 | printk("\nPADDR: "); | 160 | printk("\nPADDR: "); |
162 | for (i = first; i < last; i++) | 161 | for (i = first; i < last; i++) |
163 | printk("%08x ", entry[i].frame); | 162 | printk("%08x ", pgtbl[i].frame); |
164 | printk("\nOWNER: "); | 163 | printk("\nOWNER: "); |
165 | for (i = first; i < last; i++) | 164 | for (i = first; i < last; i++) |
166 | printk("%08x ", entry[i].owner); | 165 | printk("%08x ", pgtbl[i].owner); |
167 | printk("\n"); | 166 | printk("\n"); |
168 | } | 167 | } |
169 | 168 | ||
@@ -181,7 +180,6 @@ EXPORT_SYMBOL(vdma_alloc); | |||
181 | */ | 180 | */ |
182 | int vdma_free(unsigned long laddr) | 181 | int vdma_free(unsigned long laddr) |
183 | { | 182 | { |
184 | VDMA_PGTBL_ENTRY *pgtbl = (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
185 | int i; | 183 | int i; |
186 | 184 | ||
187 | i = laddr >> 12; | 185 | i = laddr >> 12; |
@@ -213,8 +211,6 @@ EXPORT_SYMBOL(vdma_free); | |||
213 | */ | 211 | */ |
214 | int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) | 212 | int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) |
215 | { | 213 | { |
216 | VDMA_PGTBL_ENTRY *pgtbl = | ||
217 | (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
218 | int first, pages, npages; | 214 | int first, pages, npages; |
219 | 215 | ||
220 | if (laddr > 0xffffff) { | 216 | if (laddr > 0xffffff) { |
@@ -289,8 +285,6 @@ unsigned long vdma_phys2log(unsigned long paddr) | |||
289 | { | 285 | { |
290 | int i; | 286 | int i; |
291 | int frame; | 287 | int frame; |
292 | VDMA_PGTBL_ENTRY *pgtbl = | ||
293 | (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
294 | 288 | ||
295 | frame = paddr & ~(VDMA_PAGESIZE - 1); | 289 | frame = paddr & ~(VDMA_PAGESIZE - 1); |
296 | 290 | ||
@@ -312,9 +306,6 @@ EXPORT_SYMBOL(vdma_phys2log); | |||
312 | */ | 306 | */ |
313 | unsigned long vdma_log2phys(unsigned long laddr) | 307 | unsigned long vdma_log2phys(unsigned long laddr) |
314 | { | 308 | { |
315 | VDMA_PGTBL_ENTRY *pgtbl = | ||
316 | (VDMA_PGTBL_ENTRY *) vdma_pagetable_start; | ||
317 | |||
318 | return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1)); | 309 | return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1)); |
319 | } | 310 | } |
320 | 311 | ||
@@ -564,3 +555,5 @@ int vdma_get_enable(int channel) | |||
564 | 555 | ||
565 | return enable; | 556 | return enable; |
566 | } | 557 | } |
558 | |||
559 | arch_initcall(vdma_init); | ||