/*
 * include/asm-sh/io_bigsur.c
 *
 * By Dustin McIntire (dustin@sensoria.com) (c)2001
 * Derived from io_hd64465.h, which bore the message:
 * By Greg Banks <gbanks@pocketpenguins.com>
 * (c) 2000 PocketPenguins Inc. 
 * and from io_hd64461.h, which bore the message:
 * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 *
 * IO functions for a Hitachi Big Sur Evaluation Board.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/bigsur/bigsur.h>

/* Low iomap maps port 0-1K to addresses in 8byte chunks */
#define BIGSUR_IOMAP_LO_THRESH 0x400
#define BIGSUR_IOMAP_LO_SHIFT	3
#define BIGSUR_IOMAP_LO_MASK	((1<<BIGSUR_IOMAP_LO_SHIFT)-1)
#define BIGSUR_IOMAP_LO_NMAP	(BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT)
static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP];
static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];

/* High iomap maps port 1K-64K to addresses in 1K chunks */
#define BIGSUR_IOMAP_HI_THRESH 0x10000
#define BIGSUR_IOMAP_HI_SHIFT	10
#define BIGSUR_IOMAP_HI_MASK	((1<<BIGSUR_IOMAP_HI_SHIFT)-1)
#define BIGSUR_IOMAP_HI_NMAP	(BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT)
static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];

void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
{
	u32 port, endport = baseport + nports;

	pr_debug("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n",
		 baseport, nports, addr);
	    
	for (port = baseport ;
	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
	    	pr_debug("    maplo[0x%x] = 0x%08x\n", port, addr);
    	    bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr;
    	    bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift;
	    	addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
	}

	for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
	    	pr_debug("    maphi[0x%x] = 0x%08x\n", port, addr);
    	    bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr;
    	    bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift;
	    	addr += (1<<(BIGSUR_IOMAP_HI_SHIFT));
	}
}
EXPORT_SYMBOL(bigsur_port_map);

void bigsur_port_unmap(u32 baseport, u32 nports)
{
	u32 port, endport = baseport + nports;
	
	pr_debug("bigsur_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports);

	for (port = baseport ;
	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
		bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
	}

	for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
		bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
	}
}
EXPORT_SYMBOL(bigsur_port_unmap);

unsigned long bigsur_isa_port2addr(unsigned long port)
{
	unsigned long addr = 0;
	unsigned char shift;

	/* Physical address not in P0, do nothing */
	if (PXSEG(port)) {
		addr = port;
	/* physical address in P0, map to P2 */
	} else if (port >= 0x30000) {
		addr = P2SEGADDR(port);
	/* Big Sur I/O + HD64465 registers 0x10000-0x30000 */
	} else if (port >= BIGSUR_IOMAP_HI_THRESH) {
		addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH);
	/* Handle remapping of high IO/PCI IO ports */
	} else if (port >= BIGSUR_IOMAP_LO_THRESH) {
		addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT];
		shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT];

		if (addr != 0)
			addr += (port & BIGSUR_IOMAP_HI_MASK) << shift;
	} else {
		/* Handle remapping of low IO ports */
		addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT];
		shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT];

		if (addr != 0)
			addr += (port & BIGSUR_IOMAP_LO_MASK) << shift;
	}

	pr_debug("%s(0x%08lx) = 0x%08lx\n", __FUNCTION__, port, addr);

	return addr;
}

