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