8e9fe775c890faf95184c45d388134ffd13c7577
[pandora-kernel.git] / arch / arm / plat-omap / vram.c
1 /*
2  * linux/arch/arm/plat-omap/vram.c
3  *
4  * Copyright (C) 2008 Nokia Corporation
5  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6  *
7  * Some code and ideas taken from drivers/video/omap/ driver
8  * by Imre Deak.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published by
12  * the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 /*#define DEBUG*/
24
25 #include <linux/vmalloc.h>
26 #include <linux/kernel.h>
27 #include <linux/mm.h>
28 #include <linux/list.h>
29 #include <linux/dma-mapping.h>
30 #include <linux/proc_fs.h>
31 #include <linux/seq_file.h>
32 #include <linux/bootmem.h>
33 #include <linux/omapfb.h>
34
35 #include <asm/setup.h>
36
37 #include <mach/sram.h>
38 #include <mach/vram.h>
39
40 #ifdef DEBUG
41 #define DBG(format, ...) printk(KERN_DEBUG "VRAM: " format, ## __VA_ARGS__)
42 #else
43 #define DBG(format, ...)
44 #endif
45
46 #define OMAP2_SRAM_START                0x40200000
47 /* Maximum size, in reality this is smaller if SRAM is partially locked. */
48 #define OMAP2_SRAM_SIZE                 0xa0000         /* 640k */
49
50 #define REG_MAP_SIZE(_page_cnt) \
51         ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
52 #define REG_MAP_PTR(_rg, _page_nr) \
53         (((_rg)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
54 #define REG_MAP_MASK(_page_nr) \
55         (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
56
57 #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
58
59 /* postponed regions are used to temporarily store region information at boot
60  * time when we cannot yet allocate the region list */
61 #define MAX_POSTPONED_REGIONS 10
62
63 static bool vram_initialized;
64 static int postponed_cnt __initdata;
65 static struct {
66         unsigned long paddr;
67         size_t size;
68 } postponed_regions[MAX_POSTPONED_REGIONS] __initdata;
69
70 struct vram_alloc {
71         struct list_head list;
72         unsigned long paddr;
73         unsigned pages;
74 };
75
76 struct vram_region {
77         struct list_head list;
78         struct list_head alloc_list;
79         unsigned long paddr;
80         unsigned pages;
81 };
82
83 static DEFINE_MUTEX(region_mutex);
84 static LIST_HEAD(region_list);
85
86 static inline int region_mem_type(unsigned long paddr)
87 {
88         if (paddr >= OMAP2_SRAM_START &&
89             paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
90                 return OMAPFB_MEMTYPE_SRAM;
91         else
92                 return OMAPFB_MEMTYPE_SDRAM;
93 }
94
95 static struct vram_region *omap_vram_create_region(unsigned long paddr,
96                 unsigned pages)
97 {
98         struct vram_region *rm;
99
100         rm = kzalloc(sizeof(*rm), GFP_KERNEL);
101
102         if (rm) {
103                 INIT_LIST_HEAD(&rm->alloc_list);
104                 rm->paddr = paddr;
105                 rm->pages = pages;
106         }
107
108         return rm;
109 }
110
111 #if 0
112 static void omap_vram_free_region(struct vram_region *vr)
113 {
114         list_del(&vr->list);
115         kfree(vr);
116 }
117 #endif
118
119 static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
120                 unsigned long paddr, unsigned pages)
121 {
122         struct vram_alloc *va;
123         struct vram_alloc *new;
124
125         new = kzalloc(sizeof(*va), GFP_KERNEL);
126
127         if (!new)
128                 return NULL;
129
130         new->paddr = paddr;
131         new->pages = pages;
132
133         list_for_each_entry(va, &vr->alloc_list, list) {
134                 if (va->paddr > new->paddr)
135                         break;
136         }
137
138         list_add_tail(&new->list, &va->list);
139
140         return new;
141 }
142
143 static void omap_vram_free_allocation(struct vram_alloc *va)
144 {
145         list_del(&va->list);
146         kfree(va);
147 }
148
149 int omap_vram_add_region(unsigned long paddr, size_t size)
150 {
151         struct vram_region *rm;
152         unsigned pages;
153
154         if (vram_initialized) {
155                 DBG("adding region paddr %08lx size %d\n",
156                                 paddr, size);
157
158                 size &= PAGE_MASK;
159                 pages = size >> PAGE_SHIFT;
160
161                 rm = omap_vram_create_region(paddr, pages);
162                 if (rm == NULL)
163                         return -ENOMEM;
164
165                 list_add(&rm->list, &region_list);
166         } else {
167                 if (postponed_cnt == MAX_POSTPONED_REGIONS)
168                         return -ENOMEM;
169
170                 postponed_regions[postponed_cnt].paddr = paddr;
171                 postponed_regions[postponed_cnt].size = size;
172
173                 ++postponed_cnt;
174         }
175         return 0;
176 }
177
178 int omap_vram_free(unsigned long paddr, size_t size)
179 {
180         struct vram_region *rm;
181         struct vram_alloc *alloc;
182         unsigned start, end;
183
184         DBG("free mem paddr %08lx size %d\n", paddr, size);
185
186         size = PAGE_ALIGN(size);
187
188         mutex_lock(&region_mutex);
189
190         list_for_each_entry(rm, &region_list, list) {
191                 list_for_each_entry(alloc, &rm->alloc_list, list) {
192                         start = alloc->paddr;
193                         end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
194
195                         if (start >= paddr && end < paddr + size)
196                                 goto found;
197                 }
198         }
199
200         mutex_unlock(&region_mutex);
201         return -EINVAL;
202
203 found:
204         omap_vram_free_allocation(alloc);
205
206         mutex_unlock(&region_mutex);
207         return 0;
208 }
209 EXPORT_SYMBOL(omap_vram_free);
210
211 static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
212 {
213         struct vram_region *rm;
214         struct vram_alloc *alloc;
215         size_t size;
216
217         size = pages << PAGE_SHIFT;
218
219         list_for_each_entry(rm, &region_list, list) {
220                 unsigned long start, end;
221
222                 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
223
224                 if (region_mem_type(rm->paddr) != region_mem_type(paddr))
225                         continue;
226
227                 start = rm->paddr;
228                 end = start + (rm->pages << PAGE_SHIFT) - 1;
229                 if (start > paddr || end < paddr + size - 1)
230                         continue;
231
232                 DBG("block ok, checking allocs\n");
233
234                 list_for_each_entry(alloc, &rm->alloc_list, list) {
235                         end = alloc->paddr - 1;
236
237                         if (start <= paddr && end >= paddr + size - 1)
238                                 goto found;
239
240                         start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
241                 }
242
243                 end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
244
245                 if (!(start <= paddr && end >= paddr + size - 1))
246                         continue;
247 found:
248                 DBG("FOUND area start %lx, end %lx\n", start, end);
249
250                 if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
251                         return -ENOMEM;
252
253                 return 0;
254         }
255
256         return -ENOMEM;
257 }
258
259 int omap_vram_reserve(unsigned long paddr, size_t size)
260 {
261         unsigned pages;
262         int r;
263
264         DBG("reserve mem paddr %08lx size %d\n", paddr, size);
265
266         size = PAGE_ALIGN(size);
267         pages = size >> PAGE_SHIFT;
268
269         mutex_lock(&region_mutex);
270
271         r = _omap_vram_reserve(paddr, pages);
272
273         mutex_unlock(&region_mutex);
274
275         return r;
276 }
277 EXPORT_SYMBOL(omap_vram_reserve);
278
279 static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
280 {
281         struct vram_region *rm;
282         struct vram_alloc *alloc;
283
284         list_for_each_entry(rm, &region_list, list) {
285                 unsigned long start, end;
286
287                 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
288
289                 if (region_mem_type(rm->paddr) != mtype)
290                         continue;
291
292                 start = rm->paddr;
293
294                 list_for_each_entry(alloc, &rm->alloc_list, list) {
295                         end = alloc->paddr;
296
297                         if (end - start >= pages << PAGE_SHIFT)
298                                 goto found;
299
300                         start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
301                 }
302
303                 end = rm->paddr + (rm->pages << PAGE_SHIFT);
304 found:
305                 if (end - start < pages << PAGE_SHIFT)
306                         continue;
307
308                 DBG("FOUND %lx, end %lx\n", start, end);
309
310                 alloc = omap_vram_create_allocation(rm, start, pages);
311                 if (alloc == NULL)
312                         return -ENOMEM;
313
314                 *paddr = start;
315
316                 return 0;
317         }
318
319         return -ENOMEM;
320 }
321
322 int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr)
323 {
324         unsigned pages;
325         int r;
326
327         BUG_ON(mtype > OMAPFB_MEMTYPE_MAX || !size);
328
329         DBG("alloc mem type %d size %d\n", mtype, size);
330
331         size = PAGE_ALIGN(size);
332         pages = size >> PAGE_SHIFT;
333
334         mutex_lock(&region_mutex);
335
336         r = _omap_vram_alloc(mtype, pages, paddr);
337
338         mutex_unlock(&region_mutex);
339
340         return r;
341 }
342 EXPORT_SYMBOL(omap_vram_alloc);
343
344 #ifdef CONFIG_PROC_FS
345 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
346 {
347         struct list_head *l = v;
348
349         (*pos)++;
350
351         if (list_is_last(l, &region_list))
352                 return NULL;
353
354         return l->next;
355 }
356
357 static void *r_start(struct seq_file *m, loff_t *pos)
358 {
359         loff_t p = *pos;
360         struct list_head *l = &region_list;
361
362         mutex_lock(&region_mutex);
363
364         do {
365                 l = l->next;
366                 if (l == &region_list)
367                         return NULL;
368         } while (p--);
369
370         return l;
371 }
372
373 static void r_stop(struct seq_file *m, void *v)
374 {
375         mutex_unlock(&region_mutex);
376 }
377
378 static int r_show(struct seq_file *m, void *v)
379 {
380         struct vram_region *vr;
381         struct vram_alloc *va;
382         unsigned size;
383
384         vr = list_entry(v, struct vram_region, list);
385
386         size = vr->pages << PAGE_SHIFT;
387
388         seq_printf(m, "%08lx-%08lx (%d bytes)\n",
389                         vr->paddr, vr->paddr + size - 1,
390                         size);
391
392         list_for_each_entry(va, &vr->alloc_list, list) {
393                 size = va->pages << PAGE_SHIFT;
394                 seq_printf(m, "    %08lx-%08lx (%d bytes)\n",
395                                 va->paddr, va->paddr + size - 1,
396                                 size);
397         }
398
399
400
401         return 0;
402 }
403
404 static const struct seq_operations resource_op = {
405         .start  = r_start,
406         .next   = r_next,
407         .stop   = r_stop,
408         .show   = r_show,
409 };
410
411 static int vram_open(struct inode *inode, struct file *file)
412 {
413         return seq_open(file, &resource_op);
414 }
415
416 static const struct file_operations proc_vram_operations = {
417         .open           = vram_open,
418         .read           = seq_read,
419         .llseek         = seq_lseek,
420         .release        = seq_release,
421 };
422
423 static int __init omap_vram_create_proc(void)
424 {
425         proc_create("omap-vram", 0, NULL, &proc_vram_operations);
426
427         return 0;
428 }
429 #endif
430
431 static __init int omap_vram_init(void)
432 {
433         int i, r;
434
435         vram_initialized = 1;
436
437         for (i = 0; i < postponed_cnt; i++)
438                 omap_vram_add_region(postponed_regions[i].paddr,
439                                 postponed_regions[i].size);
440
441 #ifdef CONFIG_PROC_FS
442         r = omap_vram_create_proc();
443         if (r)
444                 return -ENOMEM;
445 #endif
446
447         return 0;
448 }
449
450 arch_initcall(omap_vram_init);
451
452 /* boottime vram alloc stuff */
453
454 /* set from board file */
455 static u32 omapfb_sram_vram_start __initdata;
456 static u32 omapfb_sram_vram_size __initdata;
457
458 /* set from board file */
459 static u32 omapfb_sdram_vram_start __initdata;
460 static u32 omapfb_sdram_vram_size __initdata;
461
462 /* set from kernel cmdline */
463 static u32 omapfb_def_sdram_vram_size __initdata;
464 static u32 omapfb_def_sdram_vram_start __initdata;
465
466 static void __init omapfb_early_vram(char **p)
467 {
468         omapfb_def_sdram_vram_size = memparse(*p, p);
469         if (**p == ',')
470                 omapfb_def_sdram_vram_start = simple_strtoul((*p) + 1, p, 16);
471 }
472 __early_param("vram=", omapfb_early_vram);
473
474 /*
475  * Called from map_io. We need to call to this early enough so that we
476  * can reserve the fixed SDRAM regions before VM could get hold of them.
477  */
478 void __init omapfb_reserve_sdram(void)
479 {
480         struct bootmem_data     *bdata;
481         unsigned long           sdram_start, sdram_size;
482         u32 paddr;
483         u32 size = 0;
484
485         /* cmdline arg overrides the board file definition */
486         if (omapfb_def_sdram_vram_size) {
487                 size = omapfb_def_sdram_vram_size;
488                 paddr = omapfb_def_sdram_vram_start;
489         }
490
491         if (!size) {
492                 size = omapfb_sdram_vram_size;
493                 paddr = omapfb_sdram_vram_start;
494         }
495
496 #ifdef CONFIG_OMAP2_DSS_VRAM_SIZE
497         if (!size) {
498                 size = CONFIG_OMAP2_DSS_VRAM_SIZE * 1024 * 1024;
499                 paddr = 0;
500         }
501 #endif
502
503         if (!size)
504                 return;
505
506         size = PAGE_ALIGN(size);
507
508         bdata = NODE_DATA(0)->bdata;
509         sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
510         sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
511
512         if (paddr) {
513                 if ((paddr & ~PAGE_MASK) || paddr < sdram_start ||
514                                 paddr + size > sdram_start + sdram_size) {
515                         printk(KERN_ERR "Illegal SDRAM region for VRAM\n");
516                         return;
517                 }
518
519                 if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) {
520                         pr_err("FB: failed to reserve VRAM\n");
521                         return;
522                 }
523         } else {
524                 if (size > sdram_size) {
525                         printk(KERN_ERR "Illegal SDRAM size for VRAM\n");
526                         return;
527                 }
528
529                 paddr = virt_to_phys(alloc_bootmem_pages(size));
530                 BUG_ON(paddr & ~PAGE_MASK);
531         }
532
533         omap_vram_add_region(paddr, size);
534
535         pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
536 }
537
538 /*
539  * Called at sram init time, before anything is pushed to the SRAM stack.
540  * Because of the stack scheme, we will allocate everything from the
541  * start of the lowest address region to the end of SRAM. This will also
542  * include padding for page alignment and possible holes between regions.
543  *
544  * As opposed to the SDRAM case, we'll also do any dynamic allocations at
545  * this point, since the driver built as a module would have problem with
546  * freeing / reallocating the regions.
547  */
548 unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
549                                   unsigned long sram_vstart,
550                                   unsigned long sram_size,
551                                   unsigned long pstart_avail,
552                                   unsigned long size_avail)
553 {
554         unsigned long                   pend_avail;
555         unsigned long                   reserved;
556         u32 paddr;
557         u32 size;
558
559         paddr = omapfb_sram_vram_start;
560         size = omapfb_sram_vram_size;
561
562         if (!size)
563                 return 0;
564
565         reserved = 0;
566         pend_avail = pstart_avail + size_avail;
567
568         if (!paddr) {
569                 /* Dynamic allocation */
570                 if ((size_avail & PAGE_MASK) < size) {
571                         printk(KERN_ERR "Not enough SRAM for VRAM\n");
572                         return 0;
573                 }
574                 size_avail = (size_avail - size) & PAGE_MASK;
575                 paddr = pstart_avail + size_avail;
576         }
577
578         if (paddr < sram_pstart ||
579                         paddr + size > sram_pstart + sram_size) {
580                 printk(KERN_ERR "Illegal SRAM region for VRAM\n");
581                 return 0;
582         }
583
584         /* Reserve everything above the start of the region. */
585         if (pend_avail - paddr > reserved)
586                 reserved = pend_avail - paddr;
587         size_avail = pend_avail - reserved - pstart_avail;
588
589         omap_vram_add_region(paddr, size);
590
591         if (reserved)
592                 pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
593
594         return reserved;
595 }
596
597 void __init omap2_set_sdram_vram(u32 size, u32 start)
598 {
599         omapfb_sdram_vram_start = start;
600         omapfb_sdram_vram_size = size;
601 }
602
603 void __init omap2_set_sram_vram(u32 size, u32 start)
604 {
605         omapfb_sram_vram_start = start;
606         omapfb_sram_vram_size = size;
607 }
608
609 #endif
610