/*
 * Support for Medifield PNW Camera Imaging ISP subsystem.
 *
 * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
 *
 * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 */
/*
 * ISP MMU driver for classic two-level page tables
 */
#ifndef	__ISP_MMU_H__
#define	__ISP_MMU_H__

#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/slab.h>

/*
 * do not change these values, the page size for ISP must be the
 * same as kernel's page size.
 */
#define	ISP_PAGE_OFFSET		12
#define	ISP_PAGE_SIZE		(1U << ISP_PAGE_OFFSET)
#define	ISP_PAGE_MASK		(~(phys_addr_t)(ISP_PAGE_SIZE - 1))

#define	ISP_L1PT_OFFSET		22
#define	ISP_L1PT_MASK		(~((1U << ISP_L1PT_OFFSET) - 1))

#define	ISP_L2PT_OFFSET		12
#define	ISP_L2PT_MASK		(~(ISP_L1PT_MASK|(~(ISP_PAGE_MASK))))

#define	ISP_L1PT_PTES		1024
#define	ISP_L2PT_PTES		1024

#define	ISP_PTR_TO_L1_IDX(x)	((((x) & ISP_L1PT_MASK)) \
					>> ISP_L1PT_OFFSET)

#define	ISP_PTR_TO_L2_IDX(x)	((((x) & ISP_L2PT_MASK)) \
					>> ISP_L2PT_OFFSET)

#define	ISP_PAGE_ALIGN(x)	(((x) + (ISP_PAGE_SIZE-1)) \
					& ISP_PAGE_MASK)

#define	ISP_PT_TO_VIRT(l1_idx, l2_idx, offset) do {\
		((l1_idx) << ISP_L1PT_OFFSET) | \
		((l2_idx) << ISP_L2PT_OFFSET) | \
		(offset)\
} while (0)

#define	pgnr_to_size(pgnr)	((pgnr) << ISP_PAGE_OFFSET)
#define	size_to_pgnr_ceil(size)	(((size) + (1 << ISP_PAGE_OFFSET) - 1)\
						>> ISP_PAGE_OFFSET)
#define	size_to_pgnr_bottom(size)	((size) >> ISP_PAGE_OFFSET)

struct isp_mmu;

struct isp_mmu_client {
	/*
	 * const value
	 *
	 * @name:
	 *      driver name
	 * @pte_valid_mask:
	 *      should be 1 bit valid data, meaning the value should
	 *      be power of 2.
	 */
	char *name;
	unsigned int pte_valid_mask;
	unsigned int null_pte;

	/*
	 * set/get page directory base address (physical address).
	 *
	 * must be provided.
	 */
	int (*set_pd_base) (struct isp_mmu *mmu,
			phys_addr_t pd_base);
	unsigned int (*get_pd_base) (struct isp_mmu *mmu, phys_addr_t pd_base);
	/*
	 * callback to flush tlb.
	 *
	 * tlb_flush_range will at least flush TLBs containing
	 * address mapping from addr to addr + size.
	 *
	 * tlb_flush_all will flush all TLBs.
	 *
	 * tlb_flush_all is must be provided. if tlb_flush_range is
	 * not valid, it will set to tlb_flush_all by default.
	 */
	void (*tlb_flush_range) (struct isp_mmu *mmu,
				 unsigned int addr, unsigned int size);
	void (*tlb_flush_all) (struct isp_mmu *mmu);
	unsigned int (*phys_to_pte) (struct isp_mmu *mmu,
				     phys_addr_t phys);
	phys_addr_t (*pte_to_phys) (struct isp_mmu *mmu,
				    unsigned int pte);

};

struct isp_mmu {
	struct isp_mmu_client *driver;
	unsigned int l1_pte;
	int l2_pgt_refcount[ISP_L1PT_PTES];
	phys_addr_t base_address;

	struct mutex pt_mutex;
	struct kmem_cache *tbl_cache;
};

/* flags for PDE and PTE */
#define	ISP_PTE_VALID_MASK(mmu)	\
	((mmu)->driver->pte_valid_mask)

#define	ISP_PTE_VALID(mmu, pte)	\
	((pte) & ISP_PTE_VALID_MASK(mmu))

#define	NULL_PAGE	((phys_addr_t)(-1) & ISP_PAGE_MASK)
#define	PAGE_VALID(page)	((page) != NULL_PAGE)

/*
 * init mmu with specific mmu driver.
 */
int isp_mmu_init(struct isp_mmu *mmu, struct isp_mmu_client *driver);
/*
 * cleanup all mmu related things.
 */
void isp_mmu_exit(struct isp_mmu *mmu);

/*
 * setup/remove address mapping for pgnr continous physical pages
 * and isp_virt.
 *
 * map/unmap is mutex lock protected, and caller does not have
 * to do lock/unlock operation.
 *
 * map/unmap will not flush tlb, and caller needs to deal with
 * this itself.
 */
int isp_mmu_map(struct isp_mmu *mmu, unsigned int isp_virt,
		phys_addr_t phys, unsigned int pgnr);

void isp_mmu_unmap(struct isp_mmu *mmu, unsigned int isp_virt,
		   unsigned int pgnr);

static inline void isp_mmu_flush_tlb_all(struct isp_mmu *mmu)
{
	if (mmu->driver && mmu->driver->tlb_flush_all)
		mmu->driver->tlb_flush_all(mmu);
}

#define isp_mmu_flush_tlb isp_mmu_flush_tlb_all

static inline void isp_mmu_flush_tlb_range(struct isp_mmu *mmu,
		unsigned int start, unsigned int size)
{
	if (mmu->driver && mmu->driver->tlb_flush_range)
		mmu->driver->tlb_flush_range(mmu, start, size);
}

#endif /* ISP_MMU_H_ */
