/*
 * barebox - io.h IO routines
 *
 * Copyright (c) 2005 blackfin.uclinux.org
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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
 */

#ifndef _BLACKFIN_IO_H
#define _BLACKFIN_IO_H

/* function prototypes for CF support */
extern void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words);
extern void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words);
extern unsigned char cf_inb(volatile unsigned char *addr);
extern void cf_outb(unsigned char val, volatile unsigned char* addr);

/*
 * These are for ISA/PCI shared memory _only_ and should never be used
 * on any other type of memory, including Zorro memory. They are meant to
 * access the bus in the bus byte order which is little-endian!.
 *
 * readX/writeX() are used to access memory mapped devices. On some
 * architectures the memory mapped IO stuff needs to be accessed
 * differently. On the m68k architecture, we just read/write the
 * memory location directly.
 */


#define readb(addr)		({ unsigned char __v = (*(volatile unsigned char *) (addr));asm("ssync;"); __v; })
#define readw(addr)		({ unsigned short __v = (*(volatile unsigned short *) (addr)); asm("ssync;");__v; })
#define readl(addr)		({ unsigned int __v = (*(volatile unsigned int *) (addr));asm("ssync;"); __v; })

#define writeb(b,addr)		{((*(volatile unsigned char *) (addr)) = (b)); asm("ssync;");}
#define writew(b,addr)		{((*(volatile unsigned short *) (addr)) = (b)); asm("ssync;");}
#define writel(b,addr)		{((*(volatile unsigned int *) (addr)) = (b)); asm("ssync;");}

#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))

#define inb_p(addr)		readb((addr) + BF533_PCIIO_BASE)
#define inb(addr)		cf_inb((volatile unsigned char*)(addr))

#define outb(x,addr)		cf_outb((unsigned char)(x), (volatile unsigned char*)(addr))
#define outb_p(x,addr)		outb(x, (addr) + BF533_PCIIO_BASE)

#define inw(addr)		readw((addr) + BF533_PCIIO_BASE)
#define inl(addr)		readl((addr) + BF533_PCIIO_BASE)

#define outw(x,addr)		writew(x, (addr) + BF533_PCIIO_BASE)
#define outl(x,addr)		writel(x, (addr) + BF533_PCIIO_BASE)

#define insb(port, addr, count)	memcpy((void*)addr, (void*)(BF533_PCIIO_BASE + port), count)
#define insw(port, addr, count)	cf_insw((unsigned short*)addr, (unsigned short*)(port), (count))
#define insl(port, addr, count)	memcpy((void*)addr, (void*)(BF533_PCIIO_BASE + port), (4*count))

#define outsb(port,addr,count)	memcpy((void*)(BF533_PCIIO_BASE + port), (void*)addr, count)
#define outsw(port,addr,count)	cf_outsw((unsigned short*)(port), (unsigned short*)addr, (count))
#define outsl(port,addr,count)	memcpy((void*)(BF533_PCIIO_BASE + port), (void*)addr, (4*count))

#define IO_SPACE_LIMIT		0xffff

/* Values for nocacheflag and cmode */
#define IOMAP_FULL_CACHING	0
#define IOMAP_NOCACHE_SER	1
#define IOMAP_NOCACHE_NONSER	2
#define IOMAP_WRITETHROUGH	3

extern void *__ioremap(unsigned long physaddr, unsigned long size,
		       int cacheflag);
extern void __iounmap(void *addr, unsigned long size);

extern inline void *ioremap(unsigned long physaddr, unsigned long size)
{
	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
extern inline void *ioremap_nocache(unsigned long physaddr,
				    unsigned long size)
{
	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
extern inline void *ioremap_writethrough(unsigned long physaddr,
					 unsigned long size)
{
	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
}
extern inline void *ioremap_fullcache(unsigned long physaddr,
				      unsigned long size)
{
	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
}

extern void iounmap(void *addr);

extern void blkfin_inv_cache_all(void);
#define dma_cache_inv(_start,_size)		do { blkfin_inv_cache_all();} while (0)
#define dma_cache_wback(_start,_size)		do { } while (0)
#define dma_cache_wback_inv(_start,_size)	do { blkfin_inv_cache_all();} while (0)

#endif
