aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-11-16 04:42:46 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-11-16 04:42:46 -0500
commitdcca5cf07bcd355e4e1bd51609efe7b7d5d0a7b8 (patch)
treefb198f6a52f4790ea2468a421fc8c91a3b3648c8 /drivers/video
parent3c3dd225819112e56554162c6b37e61a31924e0c (diff)
parent966458f89d84ef5792893a01e2b7a5218c7b311d (diff)
Merge branch '3.8/vram-conversion' of git://gitorious.org/linux-omap-dss2/linux
Conflicts: drivers/video/omap2/dss/Kconfig drivers/video/omap2/omapfb/omapfb-ioctl.c drivers/video/omap2/omapfb/omapfb-main.c Merge changes to make omapfb use common dma_alloc, and remove omap's custom vram allocator.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/Kconfig3
-rw-r--r--drivers/video/omap2/Makefile1
-rw-r--r--drivers/video/omap2/dss/Kconfig12
-rw-r--r--drivers/video/omap2/omapfb/Kconfig1
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c14
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c69
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h5
-rw-r--r--drivers/video/omap2/vram.c514
8 files changed, 48 insertions, 571 deletions
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
index d877c361abd..346d67d6cf4 100644
--- a/drivers/video/omap2/Kconfig
+++ b/drivers/video/omap2/Kconfig
@@ -1,6 +1,3 @@
1config OMAP2_VRAM
2 bool
3
4config OMAP2_VRFB 1config OMAP2_VRFB
5 bool 2 bool
6 3
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index 5ddef129f79..5ea7cb9aed1 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,4 +1,3 @@
1obj-$(CONFIG_OMAP2_VRAM) += vram.o
2obj-$(CONFIG_OMAP2_VRFB) += vrfb.o 1obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
3 2
4obj-$(CONFIG_OMAP2_DSS) += dss/ 3obj-$(CONFIG_OMAP2_DSS) += dss/
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 50e880260d8..cb0f145c707 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -5,18 +5,6 @@ menuconfig OMAP2_DSS
5 5
6if OMAP2_DSS 6if OMAP2_DSS
7 7
8config OMAP2_VRAM_SIZE
9 int "VRAM size (MB)"
10 range 0 32
11 default 0
12 help
13 The amount of SDRAM to reserve at boot time for video RAM use.
14 This VRAM will be used by omapfb and other drivers that need
15 large continuous RAM area for video use.
16
17 You can also set this with "vram=<bytes>" kernel argument, or
18 in the board file.
19
20config OMAP2_DSS_DEBUG 8config OMAP2_DSS_DEBUG
21 bool "Debug support" 9 bool "Debug support"
22 default n 10 default n
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 4ea17dc3258..4cb12ce6885 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -2,7 +2,6 @@ menuconfig FB_OMAP2
2 tristate "OMAP2+ frame buffer support" 2 tristate "OMAP2+ frame buffer support"
3 depends on FB && OMAP2_DSS && !DRM_OMAP 3 depends on FB && OMAP2_DSS && !DRM_OMAP
4 4
5 select OMAP2_VRAM
6 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 5 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
7 select FB_CFB_FILLRECT 6 select FB_CFB_FILLRECT
8 select FB_CFB_COPYAREA 7 select FB_CFB_COPYAREA
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 55a39be694a..3c73adbbf5f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -31,7 +31,6 @@
31 31
32#include <video/omapdss.h> 32#include <video/omapdss.h>
33#include <video/omapvrfb.h> 33#include <video/omapvrfb.h>
34#include <plat/vram.h>
35 34
36#include "omapfb.h" 35#include "omapfb.h"
37 36
@@ -853,14 +852,15 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
853 break; 852 break;
854 853
855 case OMAPFB_GET_VRAM_INFO: { 854 case OMAPFB_GET_VRAM_INFO: {
856 unsigned long vram, free, largest;
857
858 DBG("ioctl GET_VRAM_INFO\n"); 855 DBG("ioctl GET_VRAM_INFO\n");
859 856
860 omap_vram_get_info(&vram, &free, &largest); 857 /*
861 p.vram_info.total = vram; 858 * We don't have the ability to get this vram info anymore.
862 p.vram_info.free = free; 859 * Fill in something that should keep the applications working.
863 p.vram_info.largest_free_block = largest; 860 */
861 p.vram_info.total = SZ_1M * 64;
862 p.vram_info.free = SZ_1M * 64;
863 p.vram_info.largest_free_block = SZ_1M * 64;
864 864
865 if (copy_to_user((void __user *)arg, &p.vram_info, 865 if (copy_to_user((void __user *)arg, &p.vram_info,
866 sizeof(p.vram_info))) 866 sizeof(p.vram_info)))
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index be9096ced79..408a3cce47a 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -31,7 +31,6 @@
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32 32
33#include <video/omapdss.h> 33#include <video/omapdss.h>
34#include <plat/vram.h>
35#include <video/omapvrfb.h> 34#include <video/omapvrfb.h>
36 35
37#include "omapfb.h" 36#include "omapfb.h"
@@ -1333,24 +1332,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1333 1332
1334 rg = ofbi->region; 1333 rg = ofbi->region;
1335 1334
1336 WARN_ON(atomic_read(&rg->map_count)); 1335 if (rg->token == NULL)
1337 1336 return;
1338 if (rg->paddr)
1339 if (omap_vram_free(rg->paddr, rg->size))
1340 dev_err(fbdev->dev, "VRAM FREE failed\n");
1341 1337
1342 if (rg->vaddr) 1338 WARN_ON(atomic_read(&rg->map_count));
1343 iounmap(rg->vaddr);
1344 1339
1345 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1340 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1346 /* unmap the 0 angle rotation */ 1341 /* unmap the 0 angle rotation */
1347 if (rg->vrfb.vaddr[0]) { 1342 if (rg->vrfb.vaddr[0]) {
1348 iounmap(rg->vrfb.vaddr[0]); 1343 iounmap(rg->vrfb.vaddr[0]);
1349 omap_vrfb_release_ctx(&rg->vrfb);
1350 rg->vrfb.vaddr[0] = NULL; 1344 rg->vrfb.vaddr[0] = NULL;
1351 } 1345 }
1346
1347 omap_vrfb_release_ctx(&rg->vrfb);
1352 } 1348 }
1353 1349
1350 dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
1351 &rg->attrs);
1352
1353 rg->token = NULL;
1354 rg->vaddr = NULL; 1354 rg->vaddr = NULL;
1355 rg->paddr = 0; 1355 rg->paddr = 0;
1356 rg->alloc = 0; 1356 rg->alloc = 0;
@@ -1385,7 +1385,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1385 struct omapfb_info *ofbi = FB2OFB(fbi); 1385 struct omapfb_info *ofbi = FB2OFB(fbi);
1386 struct omapfb2_device *fbdev = ofbi->fbdev; 1386 struct omapfb2_device *fbdev = ofbi->fbdev;
1387 struct omapfb2_mem_region *rg; 1387 struct omapfb2_mem_region *rg;
1388 void __iomem *vaddr; 1388 void *token;
1389 DEFINE_DMA_ATTRS(attrs);
1390 dma_addr_t dma_handle;
1389 int r; 1391 int r;
1390 1392
1391 rg = ofbi->region; 1393 rg = ofbi->region;
@@ -1400,42 +1402,43 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1400 1402
1401 size = PAGE_ALIGN(size); 1403 size = PAGE_ALIGN(size);
1402 1404
1403 if (!paddr) { 1405 WARN_ONCE(paddr,
1404 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id); 1406 "reserving memory at predefined address not supported\n");
1405 r = omap_vram_alloc(size, &paddr);
1406 } else {
1407 DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
1408 ofbi->id);
1409 r = omap_vram_reserve(paddr, size);
1410 }
1411 1407
1412 if (r) { 1408 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
1409
1410 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
1411 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
1412
1413 DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
1414
1415 token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
1416 GFP_KERNEL, &attrs);
1417
1418 if (token == NULL) {
1413 dev_err(fbdev->dev, "failed to allocate framebuffer\n"); 1419 dev_err(fbdev->dev, "failed to allocate framebuffer\n");
1414 return -ENOMEM; 1420 return -ENOMEM;
1415 } 1421 }
1416 1422
1417 if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { 1423 DBG("allocated VRAM paddr %lx, vaddr %p\n",
1418 vaddr = ioremap_wc(paddr, size); 1424 (unsigned long)dma_handle, token);
1419
1420 if (!vaddr) {
1421 dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
1422 omap_vram_free(paddr, size);
1423 return -ENOMEM;
1424 }
1425 1425
1426 DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr); 1426 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1427 } else {
1428 r = omap_vrfb_request_ctx(&rg->vrfb); 1427 r = omap_vrfb_request_ctx(&rg->vrfb);
1429 if (r) { 1428 if (r) {
1429 dma_free_attrs(fbdev->dev, size, token, dma_handle,
1430 &attrs);
1430 dev_err(fbdev->dev, "vrfb create ctx failed\n"); 1431 dev_err(fbdev->dev, "vrfb create ctx failed\n");
1431 return r; 1432 return r;
1432 } 1433 }
1433
1434 vaddr = NULL;
1435 } 1434 }
1436 1435
1437 rg->paddr = paddr; 1436 rg->attrs = attrs;
1438 rg->vaddr = vaddr; 1437 rg->token = token;
1438 rg->dma_handle = dma_handle;
1439
1440 rg->paddr = (unsigned long)dma_handle;
1441 rg->vaddr = (void __iomem *)token;
1439 rg->size = size; 1442 rg->size = size;
1440 rg->alloc = 1; 1443 rg->alloc = 1;
1441 1444
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 5ced9b334d3..5f72bf9017f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -28,6 +28,8 @@
28#endif 28#endif
29 29
30#include <linux/rwsem.h> 30#include <linux/rwsem.h>
31#include <linux/dma-attrs.h>
32#include <linux/dma-mapping.h>
31 33
32#include <video/omapdss.h> 34#include <video/omapdss.h>
33 35
@@ -49,6 +51,9 @@ extern bool omapfb_debug;
49 51
50struct omapfb2_mem_region { 52struct omapfb2_mem_region {
51 int id; 53 int id;
54 struct dma_attrs attrs;
55 void *token;
56 dma_addr_t dma_handle;
52 u32 paddr; 57 u32 paddr;
53 void __iomem *vaddr; 58 void __iomem *vaddr;
54 struct vrfb vrfb; 59 struct vrfb vrfb;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
deleted file mode 100644
index f2b15c4a75b..00000000000
--- a/drivers/video/omap2/vram.c
+++ /dev/null
@@ -1,514 +0,0 @@
1/*
2 * VRAM manager for OMAP
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*#define DEBUG*/
22
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/list.h>
26#include <linux/slab.h>
27#include <linux/seq_file.h>
28#include <linux/memblock.h>
29#include <linux/completion.h>
30#include <linux/debugfs.h>
31#include <linux/jiffies.h>
32#include <linux/module.h>
33
34#include <asm/setup.h>
35
36#include <plat/vram.h>
37
38#ifdef DEBUG
39#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
40#else
41#define DBG(format, ...)
42#endif
43
44/* postponed regions are used to temporarily store region information at boot
45 * time when we cannot yet allocate the region list */
46#define MAX_POSTPONED_REGIONS 10
47
48static bool vram_initialized;
49static int postponed_cnt;
50static struct {
51 unsigned long paddr;
52 size_t size;
53} postponed_regions[MAX_POSTPONED_REGIONS];
54
55struct vram_alloc {
56 struct list_head list;
57 unsigned long paddr;
58 unsigned pages;
59};
60
61struct vram_region {
62 struct list_head list;
63 struct list_head alloc_list;
64 unsigned long paddr;
65 unsigned pages;
66};
67
68static DEFINE_MUTEX(region_mutex);
69static LIST_HEAD(region_list);
70
71static struct vram_region *omap_vram_create_region(unsigned long paddr,
72 unsigned pages)
73{
74 struct vram_region *rm;
75
76 rm = kzalloc(sizeof(*rm), GFP_KERNEL);
77
78 if (rm) {
79 INIT_LIST_HEAD(&rm->alloc_list);
80 rm->paddr = paddr;
81 rm->pages = pages;
82 }
83
84 return rm;
85}
86
87#if 0
88static void omap_vram_free_region(struct vram_region *vr)
89{
90 list_del(&vr->list);
91 kfree(vr);
92}
93#endif
94
95static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
96 unsigned long paddr, unsigned pages)
97{
98 struct vram_alloc *va;
99 struct vram_alloc *new;
100
101 new = kzalloc(sizeof(*va), GFP_KERNEL);
102
103 if (!new)
104 return NULL;
105
106 new->paddr = paddr;
107 new->pages = pages;
108
109 list_for_each_entry(va, &vr->alloc_list, list) {
110 if (va->paddr > new->paddr)
111 break;
112 }
113
114 list_add_tail(&new->list, &va->list);
115
116 return new;
117}
118
119static void omap_vram_free_allocation(struct vram_alloc *va)
120{
121 list_del(&va->list);
122 kfree(va);
123}
124
125int omap_vram_add_region(unsigned long paddr, size_t size)
126{
127 struct vram_region *rm;
128 unsigned pages;
129
130 if (vram_initialized) {
131 DBG("adding region paddr %08lx size %d\n",
132 paddr, size);
133
134 size &= PAGE_MASK;
135 pages = size >> PAGE_SHIFT;
136
137 rm = omap_vram_create_region(paddr, pages);
138 if (rm == NULL)
139 return -ENOMEM;
140
141 list_add(&rm->list, &region_list);
142 } else {
143 if (postponed_cnt == MAX_POSTPONED_REGIONS)
144 return -ENOMEM;
145
146 postponed_regions[postponed_cnt].paddr = paddr;
147 postponed_regions[postponed_cnt].size = size;
148
149 ++postponed_cnt;
150 }
151 return 0;
152}
153
154int omap_vram_free(unsigned long paddr, size_t size)
155{
156 struct vram_region *rm;
157 struct vram_alloc *alloc;
158 unsigned start, end;
159
160 DBG("free mem paddr %08lx size %d\n", paddr, size);
161
162 size = PAGE_ALIGN(size);
163
164 mutex_lock(&region_mutex);
165
166 list_for_each_entry(rm, &region_list, list) {
167 list_for_each_entry(alloc, &rm->alloc_list, list) {
168 start = alloc->paddr;
169 end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
170
171 if (start >= paddr && end < paddr + size)
172 goto found;
173 }
174 }
175
176 mutex_unlock(&region_mutex);
177 return -EINVAL;
178
179found:
180 omap_vram_free_allocation(alloc);
181
182 mutex_unlock(&region_mutex);
183 return 0;
184}
185EXPORT_SYMBOL(omap_vram_free);
186
187static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
188{
189 struct vram_region *rm;
190 struct vram_alloc *alloc;
191 size_t size;
192
193 size = pages << PAGE_SHIFT;
194
195 list_for_each_entry(rm, &region_list, list) {
196 unsigned long start, end;
197
198 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
199
200 start = rm->paddr;
201 end = start + (rm->pages << PAGE_SHIFT) - 1;
202 if (start > paddr || end < paddr + size - 1)
203 continue;
204
205 DBG("block ok, checking allocs\n");
206
207 list_for_each_entry(alloc, &rm->alloc_list, list) {
208 end = alloc->paddr - 1;
209
210 if (start <= paddr && end >= paddr + size - 1)
211 goto found;
212
213 start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
214 }
215
216 end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
217
218 if (!(start <= paddr && end >= paddr + size - 1))
219 continue;
220found:
221 DBG("found area start %lx, end %lx\n", start, end);
222
223 if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
224 return -ENOMEM;
225
226 return 0;
227 }
228
229 return -ENOMEM;
230}
231
232int omap_vram_reserve(unsigned long paddr, size_t size)
233{
234 unsigned pages;
235 int r;
236
237 DBG("reserve mem paddr %08lx size %d\n", paddr, size);
238
239 size = PAGE_ALIGN(size);
240 pages = size >> PAGE_SHIFT;
241
242 mutex_lock(&region_mutex);
243
244 r = _omap_vram_reserve(paddr, pages);
245
246 mutex_unlock(&region_mutex);
247
248 return r;
249}
250EXPORT_SYMBOL(omap_vram_reserve);
251
252static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
253{
254 struct vram_region *rm;
255 struct vram_alloc *alloc;
256
257 list_for_each_entry(rm, &region_list, list) {
258 unsigned long start, end;
259
260 DBG("checking region %lx %d\n", rm->paddr, rm->pages);
261
262 start = rm->paddr;
263
264 list_for_each_entry(alloc, &rm->alloc_list, list) {
265 end = alloc->paddr;
266
267 if (end - start >= pages << PAGE_SHIFT)
268 goto found;
269
270 start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
271 }
272
273 end = rm->paddr + (rm->pages << PAGE_SHIFT);
274found:
275 if (end - start < pages << PAGE_SHIFT)
276 continue;
277
278 DBG("found %lx, end %lx\n", start, end);
279
280 alloc = omap_vram_create_allocation(rm, start, pages);
281 if (alloc == NULL)
282 return -ENOMEM;
283
284 *paddr = start;
285
286 return 0;
287 }
288
289 return -ENOMEM;
290}
291
292int omap_vram_alloc(size_t size, unsigned long *paddr)
293{
294 unsigned pages;
295 int r;
296
297 BUG_ON(!size);
298
299 DBG("alloc mem size %d\n", size);
300
301 size = PAGE_ALIGN(size);
302 pages = size >> PAGE_SHIFT;
303
304 mutex_lock(&region_mutex);
305
306 r = _omap_vram_alloc(pages, paddr);
307
308 mutex_unlock(&region_mutex);
309
310 return r;
311}
312EXPORT_SYMBOL(omap_vram_alloc);
313
314void omap_vram_get_info(unsigned long *vram,
315 unsigned long *free_vram,
316 unsigned long *largest_free_block)
317{
318 struct vram_region *vr;
319 struct vram_alloc *va;
320
321 *vram = 0;
322 *free_vram = 0;
323 *largest_free_block = 0;
324
325 mutex_lock(&region_mutex);
326
327 list_for_each_entry(vr, &region_list, list) {
328 unsigned free;
329 unsigned long pa;
330
331 pa = vr->paddr;
332 *vram += vr->pages << PAGE_SHIFT;
333
334 list_for_each_entry(va, &vr->alloc_list, list) {
335 free = va->paddr - pa;
336 *free_vram += free;
337 if (free > *largest_free_block)
338 *largest_free_block = free;
339 pa = va->paddr + (va->pages << PAGE_SHIFT);
340 }
341
342 free = vr->paddr + (vr->pages << PAGE_SHIFT) - pa;
343 *free_vram += free;
344 if (free > *largest_free_block)
345 *largest_free_block = free;
346 }
347
348 mutex_unlock(&region_mutex);
349}
350EXPORT_SYMBOL(omap_vram_get_info);
351
352#if defined(CONFIG_DEBUG_FS)
353static int vram_debug_show(struct seq_file *s, void *unused)
354{
355 struct vram_region *vr;
356 struct vram_alloc *va;
357 unsigned size;
358
359 mutex_lock(&region_mutex);
360
361 list_for_each_entry(vr, &region_list, list) {
362 size = vr->pages << PAGE_SHIFT;
363 seq_printf(s, "%08lx-%08lx (%d bytes)\n",
364 vr->paddr, vr->paddr + size - 1,
365 size);
366
367 list_for_each_entry(va, &vr->alloc_list, list) {
368 size = va->pages << PAGE_SHIFT;
369 seq_printf(s, " %08lx-%08lx (%d bytes)\n",
370 va->paddr, va->paddr + size - 1,
371 size);
372 }
373 }
374
375 mutex_unlock(&region_mutex);
376
377 return 0;
378}
379
380static int vram_debug_open(struct inode *inode, struct file *file)
381{
382 return single_open(file, vram_debug_show, inode->i_private);
383}
384
385static const struct file_operations vram_debug_fops = {
386 .open = vram_debug_open,
387 .read = seq_read,
388 .llseek = seq_lseek,
389 .release = single_release,
390};
391
392static int __init omap_vram_create_debugfs(void)
393{
394 struct dentry *d;
395
396 d = debugfs_create_file("vram", S_IRUGO, NULL,
397 NULL, &vram_debug_fops);
398 if (IS_ERR(d))
399 return PTR_ERR(d);
400
401 return 0;
402}
403#endif
404
405static __init int omap_vram_init(void)
406{
407 int i;
408
409 vram_initialized = 1;
410
411 for (i = 0; i < postponed_cnt; i++)
412 omap_vram_add_region(postponed_regions[i].paddr,
413 postponed_regions[i].size);
414
415#ifdef CONFIG_DEBUG_FS
416 if (omap_vram_create_debugfs())
417 pr_err("VRAM: Failed to create debugfs file\n");
418#endif
419
420 return 0;
421}
422
423arch_initcall(omap_vram_init);
424
425/* boottime vram alloc stuff */
426
427/* set from board file */
428static u32 omap_vram_sdram_start __initdata;
429static u32 omap_vram_sdram_size __initdata;
430
431/* set from kernel cmdline */
432static u32 omap_vram_def_sdram_size __initdata;
433static u32 omap_vram_def_sdram_start __initdata;
434
435static int __init omap_vram_early_vram(char *p)
436{
437 omap_vram_def_sdram_size = memparse(p, &p);
438 if (*p == ',')
439 omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16);
440 return 0;
441}
442early_param("vram", omap_vram_early_vram);
443
444/*
445 * Called from map_io. We need to call to this early enough so that we
446 * can reserve the fixed SDRAM regions before VM could get hold of them.
447 */
448void __init omap_vram_reserve_sdram_memblock(void)
449{
450 u32 paddr;
451 u32 size = 0;
452
453 /* cmdline arg overrides the board file definition */
454 if (omap_vram_def_sdram_size) {
455 size = omap_vram_def_sdram_size;
456 paddr = omap_vram_def_sdram_start;
457 }
458
459 if (!size) {
460 size = omap_vram_sdram_size;
461 paddr = omap_vram_sdram_start;
462 }
463
464#ifdef CONFIG_OMAP2_VRAM_SIZE
465 if (!size) {
466 size = CONFIG_OMAP2_VRAM_SIZE * 1024 * 1024;
467 paddr = 0;
468 }
469#endif
470
471 if (!size)
472 return;
473
474 size = ALIGN(size, SZ_2M);
475
476 if (paddr) {
477 if (paddr & ~PAGE_MASK) {
478 pr_err("VRAM start address 0x%08x not page aligned\n",
479 paddr);
480 return;
481 }
482
483 if (!memblock_is_region_memory(paddr, size)) {
484 pr_err("Illegal SDRAM region 0x%08x..0x%08x for VRAM\n",
485 paddr, paddr + size - 1);
486 return;
487 }
488
489 if (memblock_is_region_reserved(paddr, size)) {
490 pr_err("FB: failed to reserve VRAM - busy\n");
491 return;
492 }
493
494 if (memblock_reserve(paddr, size) < 0) {
495 pr_err("FB: failed to reserve VRAM - no memory\n");
496 return;
497 }
498 } else {
499 paddr = memblock_alloc(size, SZ_2M);
500 }
501
502 memblock_free(paddr, size);
503 memblock_remove(paddr, size);
504
505 omap_vram_add_region(paddr, size);
506
507 pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
508}
509
510void __init omap_vram_set_sdram_vram(u32 size, u32 start)
511{
512 omap_vram_sdram_start = start;
513 omap_vram_sdram_size = size;
514}