/*
 * File:         arch/blackfin/mach-common/cplbinfo.c
 * Based on:
 * Author:       Sonic Zhang <sonic.zhang@analog.com>
 *
 * Created:      Jan. 2005
 * Description:  Display CPLB status
 *
 * Modified:
 *               Copyright 2004-2006 Analog Devices Inc.
 *
 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
 *
 * 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, see the file COPYING, or write
 * to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>

#include <asm/current.h>
#include <asm/system.h>
#include <asm/cplb.h>
#include <asm/blackfin.h>

#define CPLB_I 1
#define CPLB_D 2

#define SYNC_SYS    SSYNC()
#define SYNC_CORE   CSYNC()

#define CPLB_BIT_PAGESIZE 0x30000

static int page_size_table[4] = {
	0x00000400,		/* 1K */
	0x00001000,		/* 4K */
	0x00100000,		/* 1M */
	0x00400000		/* 4M */
};

static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };

static int cplb_find_entry(unsigned long *cplb_addr,
			   unsigned long *cplb_data, unsigned long addr,
			   unsigned long data)
{
	int ii;

	for (ii = 0; ii < 16; ii++)
		if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] +
		    page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16]
			&& (cplb_data[ii] == data))
			return ii;

	return -1;
}

static char *cplb_print_entry(char *buf, int type)
{
	unsigned long *p_addr = dpdt_table;
	unsigned long *p_data = dpdt_table + 1;
	unsigned long *p_icount = dpdt_swapcount_table;
	unsigned long *p_ocount = dpdt_swapcount_table + 1;
	unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
	unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
	int entry = 0, used_cplb = 0;

	if (type == CPLB_I) {
		buf += sprintf(buf, "Instruction CPLB entry:\n");
		p_addr = ipdt_table;
		p_data = ipdt_table + 1;
		p_icount = ipdt_swapcount_table;
		p_ocount = ipdt_swapcount_table + 1;
		cplb_addr = (unsigned long *)ICPLB_ADDR0;
		cplb_data = (unsigned long *)ICPLB_DATA0;
	} else
		buf += sprintf(buf, "Data CPLB entry:\n");

	buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\tiCount\toCount\n");

	while (*p_addr != 0xffffffff) {
		entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
		if (entry >= 0)
			used_cplb |= 1 << entry;

		buf +=
		    sprintf(buf,
			    "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n",
			    *p_addr, *p_data,
			    page_size_string_table[(*p_data & 0x30000) >> 16],
			    (*p_data & CPLB_VALID) ? 'Y' : 'N',
			    (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount,
			    *p_ocount);

		p_addr += 2;
		p_data += 2;
		p_icount += 2;
		p_ocount += 2;
	}

	if (used_cplb != 0xffff) {
		buf += sprintf(buf, "Unused/mismatched CPLBs:\n");

		for (entry = 0; entry < 16; entry++)
			if (0 == ((1 << entry) & used_cplb)) {
				int flags = cplb_data[entry];
				buf +=
				    sprintf(buf,
					    "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n",
					    entry, cplb_addr[entry], flags,
					    page_size_string_table[(flags &
								    0x30000) >>
								   16],
					    (flags & CPLB_VALID) ? 'Y' : 'N',
					    (flags & CPLB_LOCK) ? 'Y' : 'N');
			}
	}

	buf += sprintf(buf, "\n");

	return buf;
}

static int cplbinfo_proc_output(char *buf)
{
	char *p;

	p = buf;

	p += sprintf(p, "------------------ CPLB Information ------------------\n\n");

	if (bfin_read_IMEM_CONTROL() & ENICPLB)
		p = cplb_print_entry(p, CPLB_I);
	else
		p += sprintf(p, "Instruction CPLB is disabled.\n\n");

	if (bfin_read_DMEM_CONTROL() & ENDCPLB)
		p = cplb_print_entry(p, CPLB_D);
	else
		p += sprintf(p, "Data CPLB is disabled.\n");

	return p - buf;
}

static int cplbinfo_read_proc(char *page, char **start, off_t off,
			      int count, int *eof, void *data)
{
	int len;

	len = cplbinfo_proc_output(page);
	if (len <= off + count)
		*eof = 1;
	*start = page + off;
	len -= off;
	if (len > count)
		len = count;
	if (len < 0)
		len = 0;
	return len;
}

static int cplbinfo_write_proc(struct file *file, const char __user *buffer,
			       unsigned long count, void *data)
{
	printk(KERN_INFO "Reset the CPLB swap in/out counts.\n");
	memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long));
	memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long));

	return count;
}

static int __init cplbinfo_init(void)
{
	struct proc_dir_entry *entry;

	entry = create_proc_entry("cplbinfo", 0, NULL);
	if (!entry)
		return -ENOMEM;

	entry->read_proc = cplbinfo_read_proc;
	entry->write_proc = cplbinfo_write_proc;
	entry->data = NULL;

	return 0;
}

static void __exit cplbinfo_exit(void)
{
	remove_proc_entry("cplbinfo", NULL);
}

module_init(cplbinfo_init);
module_exit(cplbinfo_exit);
