162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/arch/sh/boards/superh/microdev/io.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com) 662306a36Sopenharmony_ci * Copyright (C) 2003, 2004 SuperH, Inc. 762306a36Sopenharmony_ci * Copyright (C) 2004 Paul Mundt 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * SuperH SH4-202 MicroDev board support. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/pci.h> 1462306a36Sopenharmony_ci#include <linux/wait.h> 1562306a36Sopenharmony_ci#include <asm/io.h> 1662306a36Sopenharmony_ci#include <mach/microdev.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci /* 1962306a36Sopenharmony_ci * we need to have a 'safe' address to re-direct all I/O requests 2062306a36Sopenharmony_ci * that we do not explicitly wish to handle. This safe address 2162306a36Sopenharmony_ci * must have the following properies: 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * * writes are ignored (no exception) 2462306a36Sopenharmony_ci * * reads are benign (no side-effects) 2562306a36Sopenharmony_ci * * accesses of width 1, 2 and 4-bytes are all valid. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * The Processor Version Register (PVR) has these properties. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci#define PVR 0xff000030 /* Processor Version Register */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */ 3362306a36Sopenharmony_ci#define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */ 3462306a36Sopenharmony_ci#define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */ 3562306a36Sopenharmony_ci#define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */ 3662306a36Sopenharmony_ci#define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */ 3762306a36Sopenharmony_ci#define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */ 3862306a36Sopenharmony_ci#define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */ 3962306a36Sopenharmony_ci#define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */ 4062306a36Sopenharmony_ci#define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */ 4362306a36Sopenharmony_ci#define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */ 4462306a36Sopenharmony_ci#define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */ 4562306a36Sopenharmony_ci#define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */ 4662306a36Sopenharmony_ci#define IO_SERIAL_EXTENT 0x10ul 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */ 4962306a36Sopenharmony_ci#define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */ 5062306a36Sopenharmony_ci#define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */ 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* 5362306a36Sopenharmony_ci * map I/O ports to memory-mapped addresses 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_civoid __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci unsigned long result; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if ((offset >= IO_LAN91C111_BASE) && 6062306a36Sopenharmony_ci (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { 6162306a36Sopenharmony_ci /* 6262306a36Sopenharmony_ci * SMSC LAN91C111 Ethernet chip 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ci result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE; 6562306a36Sopenharmony_ci } else if ((offset >= IO_SUPERIO_BASE) && 6662306a36Sopenharmony_ci (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) { 6762306a36Sopenharmony_ci /* 6862306a36Sopenharmony_ci * SMSC FDC37C93xAPM SuperIO chip 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * Configuration Registers 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_ci result = IO_SUPERIO_PHYS + (offset << 1); 7362306a36Sopenharmony_ci } else if (((offset >= IO_IDE1_BASE) && 7462306a36Sopenharmony_ci (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || 7562306a36Sopenharmony_ci (offset == IO_IDE1_MISC)) { 7662306a36Sopenharmony_ci /* 7762306a36Sopenharmony_ci * SMSC FDC37C93xAPM SuperIO chip 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * IDE #1 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci result = IO_SUPERIO_PHYS + (offset << 1); 8262306a36Sopenharmony_ci } else if (((offset >= IO_IDE2_BASE) && 8362306a36Sopenharmony_ci (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) || 8462306a36Sopenharmony_ci (offset == IO_IDE2_MISC)) { 8562306a36Sopenharmony_ci /* 8662306a36Sopenharmony_ci * SMSC FDC37C93xAPM SuperIO chip 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * IDE #2 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_ci result = IO_SUPERIO_PHYS + (offset << 1); 9162306a36Sopenharmony_ci } else if ((offset >= IO_SERIAL1_BASE) && 9262306a36Sopenharmony_ci (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) { 9362306a36Sopenharmony_ci /* 9462306a36Sopenharmony_ci * SMSC FDC37C93xAPM SuperIO chip 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * Serial #1 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci result = IO_SUPERIO_PHYS + (offset << 1); 9962306a36Sopenharmony_ci } else if ((offset >= IO_SERIAL2_BASE) && 10062306a36Sopenharmony_ci (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) { 10162306a36Sopenharmony_ci /* 10262306a36Sopenharmony_ci * SMSC FDC37C93xAPM SuperIO chip 10362306a36Sopenharmony_ci * 10462306a36Sopenharmony_ci * Serial #2 10562306a36Sopenharmony_ci */ 10662306a36Sopenharmony_ci result = IO_SUPERIO_PHYS + (offset << 1); 10762306a36Sopenharmony_ci } else if ((offset >= IO_ISP1161_BASE) && 10862306a36Sopenharmony_ci (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) { 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * Philips USB ISP1161x chip 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE; 11362306a36Sopenharmony_ci } else { 11462306a36Sopenharmony_ci /* 11562306a36Sopenharmony_ci * safe default. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_ci printk("Warning: unexpected port in %s( offset = 0x%lx )\n", 11862306a36Sopenharmony_ci __func__, offset); 11962306a36Sopenharmony_ci result = PVR; 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci return (void __iomem *)result; 12362306a36Sopenharmony_ci} 124