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