1da2014a2SPaul Mundt /* 2da2014a2SPaul Mundt * linux/arch/sh/boards/superh/microdev/io.c 3da2014a2SPaul Mundt * 4da2014a2SPaul Mundt * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) 5da2014a2SPaul Mundt * Copyright (C) 2003, 2004 SuperH, Inc. 6da2014a2SPaul Mundt * Copyright (C) 2004 Paul Mundt 7da2014a2SPaul Mundt * 8da2014a2SPaul Mundt * SuperH SH4-202 MicroDev board support. 9da2014a2SPaul Mundt * 10da2014a2SPaul Mundt * May be copied or modified under the terms of the GNU General Public 11da2014a2SPaul Mundt * License. See linux/COPYING for more information. 12da2014a2SPaul Mundt */ 13da2014a2SPaul Mundt 14da2014a2SPaul Mundt #include <linux/init.h> 15da2014a2SPaul Mundt #include <linux/pci.h> 16da2014a2SPaul Mundt #include <linux/wait.h> 17da2014a2SPaul Mundt #include <asm/io.h> 187639a454SPaul Mundt #include <mach/microdev.h> 19da2014a2SPaul Mundt 20da2014a2SPaul Mundt /* 21da2014a2SPaul Mundt * we need to have a 'safe' address to re-direct all I/O requests 22da2014a2SPaul Mundt * that we do not explicitly wish to handle. This safe address 23da2014a2SPaul Mundt * must have the following properies: 24da2014a2SPaul Mundt * 25da2014a2SPaul Mundt * * writes are ignored (no exception) 26da2014a2SPaul Mundt * * reads are benign (no side-effects) 27da2014a2SPaul Mundt * * accesses of width 1, 2 and 4-bytes are all valid. 28da2014a2SPaul Mundt * 29da2014a2SPaul Mundt * The Processor Version Register (PVR) has these properties. 30da2014a2SPaul Mundt */ 31da2014a2SPaul Mundt #define PVR 0xff000030 /* Processor Version Register */ 32da2014a2SPaul Mundt 33da2014a2SPaul Mundt 34da2014a2SPaul Mundt #define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */ 35da2014a2SPaul Mundt #define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */ 36da2014a2SPaul Mundt #define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */ 37da2014a2SPaul Mundt #define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */ 38da2014a2SPaul Mundt #define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */ 39da2014a2SPaul Mundt #define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */ 40da2014a2SPaul Mundt #define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */ 41da2014a2SPaul Mundt #define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */ 42da2014a2SPaul Mundt #define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */ 43da2014a2SPaul Mundt 44da2014a2SPaul Mundt #define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */ 45da2014a2SPaul Mundt #define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */ 46da2014a2SPaul Mundt #define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */ 47da2014a2SPaul Mundt #define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */ 48da2014a2SPaul Mundt #define IO_SERIAL_EXTENT 0x10ul 49da2014a2SPaul Mundt 50da2014a2SPaul Mundt #define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */ 51da2014a2SPaul Mundt #define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */ 52da2014a2SPaul Mundt #define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */ 53da2014a2SPaul Mundt 54da2014a2SPaul Mundt /* 55da2014a2SPaul Mundt * map I/O ports to memory-mapped addresses 56da2014a2SPaul Mundt */ 57*46bc8587SPaul Mundt void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) 58da2014a2SPaul Mundt { 59da2014a2SPaul Mundt unsigned long result; 60da2014a2SPaul Mundt 61da2014a2SPaul Mundt if ((offset >= IO_LAN91C111_BASE) && 62da2014a2SPaul Mundt (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { 63da2014a2SPaul Mundt /* 64da2014a2SPaul Mundt * SMSC LAN91C111 Ethernet chip 65da2014a2SPaul Mundt */ 66da2014a2SPaul Mundt result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE; 67da2014a2SPaul Mundt } else if ((offset >= IO_SUPERIO_BASE) && 68da2014a2SPaul Mundt (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) { 69da2014a2SPaul Mundt /* 70da2014a2SPaul Mundt * SMSC FDC37C93xAPM SuperIO chip 71da2014a2SPaul Mundt * 72da2014a2SPaul Mundt * Configuration Registers 73da2014a2SPaul Mundt */ 74da2014a2SPaul Mundt result = IO_SUPERIO_PHYS + (offset << 1); 75da2014a2SPaul Mundt } else if (((offset >= IO_IDE1_BASE) && 76da2014a2SPaul Mundt (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || 77da2014a2SPaul Mundt (offset == IO_IDE1_MISC)) { 78da2014a2SPaul Mundt /* 79da2014a2SPaul Mundt * SMSC FDC37C93xAPM SuperIO chip 80da2014a2SPaul Mundt * 81da2014a2SPaul Mundt * IDE #1 82da2014a2SPaul Mundt */ 83da2014a2SPaul Mundt result = IO_SUPERIO_PHYS + (offset << 1); 84da2014a2SPaul Mundt } else if (((offset >= IO_IDE2_BASE) && 85da2014a2SPaul Mundt (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) || 86da2014a2SPaul Mundt (offset == IO_IDE2_MISC)) { 87da2014a2SPaul Mundt /* 88da2014a2SPaul Mundt * SMSC FDC37C93xAPM SuperIO chip 89da2014a2SPaul Mundt * 90da2014a2SPaul Mundt * IDE #2 91da2014a2SPaul Mundt */ 92da2014a2SPaul Mundt result = IO_SUPERIO_PHYS + (offset << 1); 93da2014a2SPaul Mundt } else if ((offset >= IO_SERIAL1_BASE) && 94da2014a2SPaul Mundt (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) { 95da2014a2SPaul Mundt /* 96da2014a2SPaul Mundt * SMSC FDC37C93xAPM SuperIO chip 97da2014a2SPaul Mundt * 98da2014a2SPaul Mundt * Serial #1 99da2014a2SPaul Mundt */ 100da2014a2SPaul Mundt result = IO_SUPERIO_PHYS + (offset << 1); 101da2014a2SPaul Mundt } else if ((offset >= IO_SERIAL2_BASE) && 102da2014a2SPaul Mundt (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) { 103da2014a2SPaul Mundt /* 104da2014a2SPaul Mundt * SMSC FDC37C93xAPM SuperIO chip 105da2014a2SPaul Mundt * 106da2014a2SPaul Mundt * Serial #2 107da2014a2SPaul Mundt */ 108da2014a2SPaul Mundt result = IO_SUPERIO_PHYS + (offset << 1); 109da2014a2SPaul Mundt } else if ((offset >= IO_ISP1161_BASE) && 110da2014a2SPaul Mundt (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) { 111da2014a2SPaul Mundt /* 112da2014a2SPaul Mundt * Philips USB ISP1161x chip 113da2014a2SPaul Mundt */ 114da2014a2SPaul Mundt result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE; 115da2014a2SPaul Mundt } else { 116da2014a2SPaul Mundt /* 117da2014a2SPaul Mundt * safe default. 118da2014a2SPaul Mundt */ 119da2014a2SPaul Mundt printk("Warning: unexpected port in %s( offset = 0x%lx )\n", 120da2014a2SPaul Mundt __func__, offset); 121da2014a2SPaul Mundt result = PVR; 122da2014a2SPaul Mundt } 123da2014a2SPaul Mundt 124*46bc8587SPaul Mundt return (void __iomem *)result; 125da2014a2SPaul Mundt } 126