/*
 * File: arch/arm/plat-omap/fb.c
 *
 * Framebuffer device registration for TI OMAP platforms
 *
 * Copyright (C) 2006 Nokia Corporation
 * Author: Imre Deak <imre.deak@nokia.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/memblock.h>
#include <linux/io.h>
#include <linux/omapfb.h>

#include <mach/hardware.h>
#include <asm/mach/map.h>

#include <plat/board.h>
#include <plat/sram.h>

#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)

static struct omapfb_platform_data omapfb_config;
static int config_invalid;
static int configured_regions;

static u64 omap_fb_dma_mask = ~(u32)0;

static struct platform_device omap_fb_device = {
	.name		= "omapfb",
	.id		= -1,
	.dev = {
		.dma_mask		= &omap_fb_dma_mask,
		.coherent_dma_mask	= ~(u32)0,
		.platform_data		= &omapfb_config,
	},
	.num_resources = 0,
};

void omapfb_set_platform_data(struct omapfb_platform_data *data)
{
}

static inline int ranges_overlap(unsigned long start1, unsigned long size1,
				 unsigned long start2, unsigned long size2)
{
	return (start1 >= start2 && start1 < start2 + size2) ||
	       (start2 >= start1 && start2 < start1 + size1);
}

static inline int range_included(unsigned long start1, unsigned long size1,
				 unsigned long start2, unsigned long size2)
{
	return start1 >= start2 && start1 + size1 <= start2 + size2;
}


/* Check if there is an overlapping region. */
static int fbmem_region_reserved(unsigned long start, size_t size)
{
	struct omapfb_mem_region *rg;
	int i;

	rg = &omapfb_config.mem_desc.region[0];
	for (i = 0; i < OMAPFB_PLANE_NUM; i++, rg++) {
		if (!rg->paddr)
			/* Empty slot. */
			continue;
		if (ranges_overlap(start, size, rg->paddr, rg->size))
			return 1;
	}
	return 0;
}

/*
 * Get the region_idx`th region from board config/ATAG and convert it to
 * our internal format.
 */
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)
		return -ENOENT;

	paddr = conf->start;
	/*
	 * Low bits encode the page allocation mode, if high bits
	 * are zero. Otherwise we need a page aligned fixed
	 * address.
	 */
	memset(rg, 0, sizeof(*rg));
	rg->type = paddr & ~PAGE_MASK;
	rg->paddr = paddr & PAGE_MASK;
	rg->size = PAGE_ALIGN(conf->size);
	return 0;
}

static int set_fbmem_region_type(struct omapfb_mem_region *rg, int mem_type,
				  unsigned long mem_start,
				  unsigned long mem_size)
{
	/*
	 * Check if the configuration specifies the type explicitly.
	 * type = 0 && paddr = 0, a default don't care case maps to
	 * the SDRAM type.
	 */
	if (rg->type || (!rg->type && !rg->paddr))
		return 0;
	if (ranges_overlap(rg->paddr, rg->size, mem_start, mem_size)) {
		rg->type = mem_type;
		return 0;
	}
	/* Can't determine it. */
	return -1;
}

static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
			      unsigned long start_avail, unsigned size_avail)
{
	unsigned long	paddr = rg->paddr;
	size_t		size = rg->size;

	if (rg->type > OMAPFB_MEMTYPE_MAX) {
		printk(KERN_ERR
			"Invalid start address for FB region %d\n", region_idx);
		return -EINVAL;
	}

	if (!rg->size) {
		printk(KERN_ERR "Zero size for FB region %d\n", region_idx);
		return -EINVAL;
	}

	if (!paddr)
		/* Allocate this dynamically, leave paddr 0 for now. */
		return 0;

	/*
	 * Fixed region for the given RAM range. Check if it's already
	 * reserved by the FB code or someone else.
	 */
	if (fbmem_region_reserved(paddr, size) ||
	    !range_included(paddr, size, start_avail, size_avail)) {
		printk(KERN_ERR "Trying to use reserved memory "
			"for FB region %d\n", region_idx);
		return -EINVAL;
	}

	return 0;
}

static int valid_sdram(unsigned long addr, unsigned long size)
{
	struct memblock_property res;

	res.base = addr;
	res.size = size;
	return !memblock_find(&res) && res.base == addr && res.size == size;
}

static int reserve_sdram(unsigned long addr, unsigned long size)
{
	if (memblock_is_region_reserved(addr, size))
		return -EBUSY;
	if (memblock_reserve(addr, size))
		return -ENOMEM;
	return 0;
}

/*
 * Called from map_io. We need to call to this early enough so that we
 * can reserve the fixed SDRAM regions before VM could get hold of them.
 */
void __init omapfb_reserve_sdram_memblock(void)
{
	unsigned long reserved = 0;
	int i;

	if (config_invalid)
		return;

	for (i = 0; ; i++) {
		struct omapfb_mem_region rg;

		if (get_fbmem_region(i, &rg) < 0)
			break;

		if (i == OMAPFB_PLANE_NUM) {
			pr_err("Extraneous FB mem configuration entries\n");
			config_invalid = 1;
			return;
		}

		/* Check if it's our memory type. */
		if (rg.type != OMAPFB_MEMTYPE_SDRAM)
			continue;

		/* Check if the region falls within SDRAM */
		if (rg.paddr && !valid_sdram(rg.paddr, rg.size))
			continue;

		if (rg.size == 0) {
			pr_err("Zero size for FB region %d\n", i);
			config_invalid = 1;
			return;
		}

		if (rg.paddr) {
			if (reserve_sdram(rg.paddr, rg.size)) {
				pr_err("Trying to use reserved memory for FB region %d\n",
					i);
				config_invalid = 1;
				return;
			}
			reserved += rg.size;
		}

		if (omapfb_config.mem_desc.region[i].size) {
			pr_err("FB region %d already set\n", i);
			config_invalid = 1;
			return;
		}

		omapfb_config.mem_desc.region[i] = rg;
		configured_regions++;
	}
	omapfb_config.mem_desc.region_cnt = i;
	if (reserved)
		pr_info("Reserving %lu bytes SDRAM for frame buffer\n",
			 reserved);
}

/*
 * Called at sram init time, before anything is pushed to the SRAM stack.
 * Because of the stack scheme, we will allocate everything from the
 * start of the lowest address region to the end of SRAM. This will also
 * include padding for page alignment and possible holes between regions.
 *
 * As opposed to the SDRAM case, we'll also do any dynamic allocations at
 * this point, since the driver built as a module would have problem with
 * freeing / reallocating the regions.
 */
unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
				  unsigned long sram_vstart,
				  unsigned long sram_size,
				  unsigned long pstart_avail,
				  unsigned long size_avail)
{
	struct omapfb_mem_region	rg;
	unsigned long			pend_avail;
	unsigned long			reserved;
	int				i;

	if (config_invalid)
		return 0;

	reserved = 0;
	pend_avail = pstart_avail + size_avail;
	for (i = 0; ; i++) {
		if (get_fbmem_region(i, &rg) < 0)
			break;
		if (i == OMAPFB_PLANE_NUM) {
			printk(KERN_ERR
				"Extraneous FB mem configuration entries\n");
			config_invalid = 1;
			return 0;
		}

		/* Check if it's our memory type. */
		if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SRAM,
				          sram_pstart, sram_size) < 0 ||
		    (rg.type != OMAPFB_MEMTYPE_SRAM))
			continue;
		BUG_ON(omapfb_config.mem_desc.region[i].size);

		if (check_fbmem_region(i, &rg, pstart_avail, size_avail) < 0) {
			config_invalid = 1;
			return 0;
		}

		if (!rg.paddr) {
			/* Dynamic allocation */
			if ((size_avail & PAGE_MASK) < rg.size) {
				printk("Not enough SRAM for FB region %d\n",
					i);
				config_invalid = 1;
				return 0;
			}
			size_avail = (size_avail - rg.size) & PAGE_MASK;
			rg.paddr = pstart_avail + size_avail;
		}
		/* Reserve everything above the start of the region. */
		if (pend_avail - rg.paddr > reserved)
			reserved = pend_avail - rg.paddr;
		size_avail = pend_avail - reserved - pstart_avail;

		/*
		 * We have a kernel mapping for this already, so the
		 * driver won't have to make one.
		 */
		rg.vaddr = (void *)(sram_vstart + rg.paddr - sram_pstart);
		omapfb_config.mem_desc.region[i] = rg;
		configured_regions++;
	}
	omapfb_config.mem_desc.region_cnt = i;
	if (reserved)
		pr_info("Reserving %lu bytes SRAM for frame buffer\n",
			 reserved);
	return reserved;
}

void omapfb_set_ctrl_platform_data(void *data)
{
	omapfb_config.ctrl_platform_data = data;
}

static inline int omap_init_fb(void)
{
	const struct omap_lcd_config *conf;

	if (config_invalid)
		return 0;
	if (configured_regions != omapfb_config.mem_desc.region_cnt) {
		printk(KERN_ERR "Invalid FB mem configuration entries\n");
		return 0;
	}
	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
	if (conf == NULL) {
		if (configured_regions)
			/* FB mem config, but no LCD config? */
			printk(KERN_ERR "Missing LCD configuration\n");
		return 0;
	}
	omapfb_config.lcd = *conf;

	return platform_device_register(&omap_fb_device);
}

arch_initcall(omap_init_fb);

#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)

static u64 omap_fb_dma_mask = ~(u32)0;
static struct omapfb_platform_data omapfb_config;

static struct platform_device omap_fb_device = {
	.name		= "omapfb",
	.id		= -1,
	.dev = {
		.dma_mask		= &omap_fb_dma_mask,
		.coherent_dma_mask	= ~(u32)0,
		.platform_data		= &omapfb_config,
	},
	.num_resources = 0,
};

void omapfb_set_platform_data(struct omapfb_platform_data *data)
{
	omapfb_config = *data;
}

static inline int omap_init_fb(void)
{
	return platform_device_register(&omap_fb_device);
}

arch_initcall(omap_init_fb);

void omapfb_reserve_sdram_memblock(void)
{
}

unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
				  unsigned long sram_vstart,
				  unsigned long sram_size,
				  unsigned long start_avail,
				  unsigned long size_avail)
{
	return 0;
}

#else

void omapfb_set_platform_data(struct omapfb_platform_data *data)
{
}

void omapfb_reserve_sdram_memblock(void)
{
}

unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
				  unsigned long sram_vstart,
				  unsigned long sram_size,
				  unsigned long start_avail,
				  unsigned long size_avail)
{
	return 0;
}

#endif
