Signed-off-by: Tomi Valkeinen <[EMAIL PROTECTED]>
---
arch/arm/plat-omap/fb.c | 22 ++-
arch/arm/plat-omap/include/mach/omapfb.h | 2 +
drivers/video/omap/dispc.c | 281 +++---------------------------
drivers/video/omap/omapfb_main.c | 11 +-
4 files changed, 48 insertions(+), 268 deletions(-)
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 3746222..8c23c9b 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -38,6 +38,9 @@
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+static int omapfb_vram_count;
+static struct omap_fbmem_config *omapfb_vram_config;
+
static struct omapfb_platform_data omapfb_config;
static int config_invalid;
static int configured_regions;
@@ -95,11 +98,11 @@ static int get_fbmem_region(int region_idx, struct
omapfb_mem_region *rg)
const struct omap_fbmem_config *conf;
u32 paddr;
- conf = omap_get_nr_config(OMAP_TAG_FBMEM,
- struct omap_fbmem_config, region_idx);
- if (conf == NULL)
+ if (region_idx >= omapfb_vram_count)
return -ENOENT;
+ conf = &omapfb_vram_config[region_idx];
+
paddr = conf->start;
/*
* Low bits encode the page allocation mode, if high bits
@@ -209,6 +212,13 @@ void __init omapfb_reserve_sdram(void)
if (rg.paddr) {
reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
reserved += rg.size;
+ omap_vram_add_region_postponed(rg.paddr, rg.size);
+ } else {
+ void *vaddr;
+ vaddr = alloc_bootmem(rg.size);
+ rg.paddr = virt_to_phys(vaddr);
+ reserved += rg.size;
+ omap_vram_add_region_postponed(rg.paddr, rg.size);
}
omapfb_config.mem_desc.region[i] = rg;
configured_regions++;
@@ -298,6 +308,12 @@ unsigned long omapfb_reserve_sram(unsigned long
sram_pstart,
return reserved;
}
+void __init omapfb_set_vram_config(struct omap_fbmem_config *config, int count)
+{
+ omapfb_vram_count = count;
+ omapfb_vram_config = config;
+}
+
void omapfb_set_ctrl_platform_data(void *data)
{
omapfb_config.ctrl_platform_data = data;
diff --git a/arch/arm/plat-omap/include/mach/omapfb.h
b/arch/arm/plat-omap/include/mach/omapfb.h
index f1cfd06..09da87f 100644
--- a/arch/arm/plat-omap/include/mach/omapfb.h
+++ b/arch/arm/plat-omap/include/mach/omapfb.h
@@ -392,6 +392,8 @@ extern int omapfb_update_window_async(struct fb_info *fbi,
/* in arch/arm/plat-omap/fb.c */
extern void omapfb_set_ctrl_platform_data(void *pdata);
+extern void omapfb_set_vram_config(struct omap_fbmem_config *config,
+ int count);
/* in arch/arm/plat-omap/fb-vram */
__init int omap_vram_add_region_postponed(unsigned long paddr, size_t size);
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index c140c21..9ae9b5d 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -18,6 +18,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
@@ -139,29 +140,12 @@
/* Maximum size, in reality this is smaller if SRAM is partially locked. */
#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */
-/* We support the SDRAM / SRAM types. See OMAPFB_PLANE_MEMTYPE_* in omapfb.h */
-#define DISPC_MEMTYPE_NUM 2
-
-#define RESMAP_SIZE(_page_cnt) \
- ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
-#define RESMAP_PTR(_res_map, _page_nr) \
- (((_res_map)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
-#define RESMAP_MASK(_page_nr) \
- (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
-
-struct resmap {
- unsigned long start;
- unsigned page_cnt;
- unsigned long *map;
-};
-
#define MAX_IRQ_HANDLERS 4
static struct {
void __iomem *base;
struct omapfb_mem_desc mem_desc;
- struct resmap *res_map[DISPC_MEMTYPE_NUM];
atomic_t map_count[OMAPFB_PLANE_NUM];
dma_addr_t palette_paddr;
@@ -992,35 +976,6 @@ static int omap_dispc_update_window(struct fb_info *fbi,
return dispc.update_mode == OMAPFB_UPDATE_DISABLED ? -ENODEV : 0;
}
-static int mmap_kern(struct omapfb_mem_region *region)
-{
- struct vm_struct *kvma;
- struct vm_area_struct vma;
- pgprot_t pgprot;
- unsigned long vaddr;
-
- kvma = get_vm_area(region->size, VM_IOREMAP);
- if (kvma == NULL) {
- dev_err(dispc.fbdev->dev, "can't get kernel vm area\n");
- return -ENOMEM;
- }
- vma.vm_mm = &init_mm;
-
- vaddr = (unsigned long)kvma->addr;
-
- pgprot = pgprot_writecombine(pgprot_kernel);
- vma.vm_start = vaddr;
- vma.vm_end = vaddr + region->size;
- if (io_remap_pfn_range(&vma, vaddr, region->paddr >> PAGE_SHIFT,
- region->size, pgprot) < 0) {
- dev_err(dispc.fbdev->dev, "kernel mmap for FBMEM failed\n");
- return -EAGAIN;
- }
- region->vaddr = (void *)vaddr;
-
- return 0;
-}
-
static void mmap_user_open(struct vm_area_struct *vma)
{
int plane = (int)vma->vm_private_data;
@@ -1074,11 +1029,6 @@ static int omap_dispc_mmap_user(struct fb_info *info,
return 0;
}
-static void unmap_kern(struct omapfb_mem_region *region)
-{
- vunmap(region->vaddr);
-}
-
static int alloc_palette_ram(void)
{
dispc.palette_vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
@@ -1097,138 +1047,6 @@ static void free_palette_ram(void)
dispc.palette_vaddr, dispc.palette_paddr);
}
-static int alloc_fbmem(struct omapfb_mem_region *region)
-{
- region->vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
- region->size, ®ion->paddr, GFP_KERNEL);
-
- if (region->vaddr == NULL) {
- dev_err(dispc.fbdev->dev, "unable to allocate FB DMA memory\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void free_fbmem(struct omapfb_mem_region *region)
-{
- dma_free_writecombine(dispc.fbdev->dev, region->size,
- region->vaddr, region->paddr);
-}
-
-static struct resmap *init_resmap(unsigned long start, size_t size)
-{
- unsigned page_cnt;
- struct resmap *res_map;
-
- page_cnt = PAGE_ALIGN(size) / PAGE_SIZE;
- res_map =
- kzalloc(sizeof(struct resmap) + RESMAP_SIZE(page_cnt), GFP_KERNEL);
- if (res_map == NULL)
- return NULL;
- res_map->start = start;
- res_map->page_cnt = page_cnt;
- res_map->map = (unsigned long *)(res_map + 1);
- return res_map;
-}
-
-static void cleanup_resmap(struct resmap *res_map)
-{
- kfree(res_map);
-}
-
-static inline int resmap_mem_type(unsigned long start)
-{
- if (start >= OMAP2_SRAM_START &&
- start < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
- return OMAPFB_MEMTYPE_SRAM;
- else
- return OMAPFB_MEMTYPE_SDRAM;
-}
-
-static inline int resmap_page_reserved(struct resmap *res_map, unsigned
page_nr)
-{
- return *RESMAP_PTR(res_map, page_nr) & RESMAP_MASK(page_nr) ? 1 : 0;
-}
-
-static inline void resmap_reserve_page(struct resmap *res_map, unsigned
page_nr)
-{
- BUG_ON(resmap_page_reserved(res_map, page_nr));
- *RESMAP_PTR(res_map, page_nr) |= RESMAP_MASK(page_nr);
-}
-
-static inline void resmap_free_page(struct resmap *res_map, unsigned page_nr)
-{
- BUG_ON(!resmap_page_reserved(res_map, page_nr));
- *RESMAP_PTR(res_map, page_nr) &= ~RESMAP_MASK(page_nr);
-}
-
-static void resmap_reserve_region(unsigned long start, size_t size)
-{
-
- struct resmap *res_map;
- unsigned start_page;
- unsigned end_page;
- int mtype;
- unsigned i;
-
- mtype = resmap_mem_type(start);
- res_map = dispc.res_map[mtype];
- dev_dbg(dispc.fbdev->dev, "reserve mem type %d start %08lx size %d\n",
- mtype, start, size);
- start_page = (start - res_map->start) / PAGE_SIZE;
- end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
- for (i = start_page; i < end_page; i++)
- resmap_reserve_page(res_map, i);
-}
-
-static void resmap_free_region(unsigned long start, size_t size)
-{
- struct resmap *res_map;
- unsigned start_page;
- unsigned end_page;
- unsigned i;
- int mtype;
-
- mtype = resmap_mem_type(start);
- res_map = dispc.res_map[mtype];
- dev_dbg(dispc.fbdev->dev, "free mem type %d start %08lx size %d\n",
- mtype, start, size);
- start_page = (start - res_map->start) / PAGE_SIZE;
- end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
- for (i = start_page; i < end_page; i++)
- resmap_free_page(res_map, i);
-}
-
-static unsigned long resmap_alloc_region(int mtype, size_t size)
-{
- unsigned i;
- unsigned total;
- unsigned start_page;
- unsigned long start;
- struct resmap *res_map = dispc.res_map[mtype];
-
- BUG_ON(mtype >= DISPC_MEMTYPE_NUM || res_map == NULL || !size);
-
- size = PAGE_ALIGN(size) / PAGE_SIZE;
- start_page = 0;
- total = 0;
- for (i = 0; i < res_map->page_cnt; i++) {
- if (resmap_page_reserved(res_map, i)) {
- start_page = i + 1;
- total = 0;
- } else if (++total == size)
- break;
- }
- if (total < size)
- return 0;
-
- start = res_map->start + start_page * PAGE_SIZE;
- resmap_reserve_region(start, size * PAGE_SIZE);
-
- return start;
-}
-
/* Note that this will only work for user mappings, we don't deal with
* kernel mappings here, so fbcon will keep using the old region.
*/
@@ -1236,34 +1054,38 @@ static int omap_dispc_setup_mem(int plane, size_t size,
int mem_type,
unsigned long *paddr)
{
struct omapfb_mem_region *rg;
- unsigned long new_addr = 0;
+ unsigned long new_paddr = 0;
+ void *new_vaddr = 0;
if ((unsigned)plane > dispc.mem_desc.region_cnt)
return -EINVAL;
- if (mem_type >= DISPC_MEMTYPE_NUM)
+ if (mem_type > OMAPFB_MEMTYPE_MAX)
return -EINVAL;
- if (dispc.res_map[mem_type] == NULL)
- return -ENOMEM;
rg = &dispc.mem_desc.region[plane];
if (size == rg->size && mem_type == rg->type)
return 0;
if (atomic_read(&dispc.map_count[plane]))
return -EBUSY;
if (rg->size != 0)
- resmap_free_region(rg->paddr, rg->size);
+ omap_vram_free(rg->paddr, rg->vaddr, rg->size);
if (size != 0) {
- new_addr = resmap_alloc_region(mem_type, size);
- if (!new_addr) {
- /* Reallocate old region. */
- resmap_reserve_region(rg->paddr, rg->size);
+ new_vaddr = omap_vram_alloc(mem_type, size, &new_paddr);
+ if (!new_vaddr) {
+ if (rg->size != 0) {
+ /* Reallocate old region. */
+ rg->vaddr = omap_vram_alloc(rg->type,
+ rg->size,
+ (unsigned long *)&rg->paddr);
+ }
return -ENOMEM;
}
}
- rg->paddr = new_addr;
+ rg->paddr = new_paddr;
+ rg->vaddr = new_vaddr;
rg->size = size;
rg->type = mem_type;
- *paddr = new_addr;
+ *paddr = new_paddr;
return 0;
}
@@ -1272,9 +1094,6 @@ static int setup_fbmem(struct omapfb_mem_desc *req_md)
{
struct omapfb_mem_region *rg;
int i;
- int r;
- unsigned long mem_start[DISPC_MEMTYPE_NUM];
- unsigned long mem_end[DISPC_MEMTYPE_NUM];
if (!req_md->region_cnt) {
dev_err(dispc.fbdev->dev, "no memory regions defined\n");
@@ -1282,63 +1101,21 @@ static int setup_fbmem(struct omapfb_mem_desc *req_md)
}
rg = &req_md->region[0];
- memset(mem_start, 0xff, sizeof(mem_start));
- memset(mem_end, 0, sizeof(mem_end));
for (i = 0; i < req_md->region_cnt; i++, rg++) {
- int mtype;
- if (rg->paddr) {
- rg->alloc = 0;
- if (rg->vaddr == NULL) {
- rg->map = 1;
- if ((r = mmap_kern(rg)) < 0)
- return r;
- }
- } else {
- if (rg->type != OMAPFB_MEMTYPE_SDRAM) {
- dev_err(dispc.fbdev->dev,
- "unsupported memory type\n");
- return -EINVAL;
- }
- rg->alloc = rg->map = 1;
- if ((r = alloc_fbmem(rg)) < 0)
- return r;
- }
- mtype = rg->type;
+ if (rg->size == 0)
+ continue;
- if (rg->paddr < mem_start[mtype])
- mem_start[mtype] = rg->paddr;
- if (rg->paddr + rg->size > mem_end[mtype])
- mem_end[mtype] = rg->paddr + rg->size;
- }
+ rg->vaddr = omap_vram_alloc(rg->type, rg->size,
+ (unsigned long *)&rg->paddr);
- for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
- unsigned long start;
- size_t size;
- if (mem_end[i] == 0)
- continue;
- start = mem_start[i];
- size = mem_end[i] - start;
- dispc.res_map[i] = init_resmap(start, size);
- r = -ENOMEM;
- if (dispc.res_map[i] == NULL)
- goto fail;
- /* Initial state is that everything is reserved. This
- * includes possible holes as well, which will never be
- * freed.
- */
- resmap_reserve_region(start, size);
+ if (rg->vaddr == NULL)
+ return -ENOMEM;
}
dispc.mem_desc = *req_md;
return 0;
-fail:
- for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
- if (dispc.res_map[i] != NULL)
- cleanup_resmap(dispc.res_map[i]);
- }
- return r;
}
static void cleanup_fbmem(void)
@@ -1346,19 +1123,9 @@ static void cleanup_fbmem(void)
struct omapfb_mem_region *rg;
int i;
- for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
- if (dispc.res_map[i] != NULL)
- cleanup_resmap(dispc.res_map[i]);
- }
rg = &dispc.mem_desc.region[0];
- for (i = 0; i < dispc.mem_desc.region_cnt; i++, rg++) {
- if (rg->alloc)
- free_fbmem(rg);
- else {
- if (rg->map)
- unmap_kern(rg);
- }
- }
+ for (i = 0; i < dispc.mem_desc.region_cnt; i++, rg++)
+ omap_vram_free(rg->paddr, rg->vaddr, rg->size);
}
static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 3bb4247..0813544 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -156,13 +156,6 @@ static int ctrl_init(struct omapfb_device *fbdev)
PAGE_ALIGN(def_vram[i]);
fbdev->mem_desc.region_cnt = i;
} else {
- struct omapfb_platform_data *conf;
-
- conf = fbdev->dev->platform_data;
- fbdev->mem_desc = conf->mem_desc;
- }
-
- if (!fbdev->mem_desc.region_cnt) {
struct lcd_panel *panel = fbdev->panel;
int def_size;
int bpp = panel->bpp;
@@ -171,8 +164,10 @@ static int ctrl_init(struct omapfb_device *fbdev)
if (bpp == 12)
bpp = 16;
def_size = def_vxres * def_vyres * bpp / 8;
- fbdev->mem_desc.region_cnt = 1;
+ fbdev->mem_desc.region_cnt = 3;
fbdev->mem_desc.region[0].size = PAGE_ALIGN(def_size);
+ fbdev->mem_desc.region[1].size = 0;
+ fbdev->mem_desc.region[2].size = 0;
}
r = fbdev->ctrl->init(fbdev, 0, &fbdev->mem_desc);
if (r < 0) {
--
1.6.0.3
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html