/*
** ccio-dma.c:
** DMA management routines for first generation cache-coherent machines.
** Program U2/Uturn in "Virtual Mode" and use the I/O MMU.
**
** (c) Copyright 2000 Grant Grundler
** (c) Copyright 2000 Ryan Bradetich
** (c) Copyright 2000 Hewlett-Packard Company
**
** 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.
**
**
** "Real Mode" operation refers to U2/Uturn chip operation.
** U2/Uturn were designed to perform coherency checks w/o using
** the I/O MMU - basically what x86 does.
**
** Philipp Rumpf has a "Real Mode" driver for PCX-W machines at:
** CVSROOT=:pserver:anonymous@198.186.203.37:/cvsroot/linux-parisc
** cvs -z3 co linux/arch/parisc/kernel/dma-rm.c
**
** I've rewritten his code to work under TPG's tree. See ccio-rm-dma.c.
**
** Drawbacks of using Real Mode are:
** o outbound DMA is slower - U2 won't prefetch data (GSC+ XQL signal).
** o Inbound DMA less efficient - U2 can't use DMA_FAST attribute.
** o Ability to do scatter/gather in HW is lost.
** o Doesn't work under PCX-U/U+ machines since they didn't follow
** the coherency design originally worked out. Only PCX-W does.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
#include <linux/iommu-helper.h>
#include <linux/export.h>
#include <asm/byteorder.h>
#include <asm/cache.h> /* for L1_CACHE_BYTES */
#include <linux/uaccess.h>
#include <asm/page.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/hardware.h> /* for register_module() */
#include <asm/parisc-device.h>
/*
** Choose "ccio" since that's what HP-UX calls it.
** Make it easier for folks to migrate from one to the other :^)
*/
#define MODULE_NAME "ccio"
#undef DEBUG_CCIO_RES
#undef DEBUG_CCIO_RUN
#undef DEBUG_CCIO_INIT
#undef DEBUG_CCIO_RUN_SG
#ifdef CONFIG_PROC_FS
/* depends on proc fs support. But costs CPU performance. */
#undef CCIO_COLLECT_STATS
#endif
#include <asm/runway.h> /* for proc_runway_root */
#ifdef DEBUG_CCIO_INIT
#define DBG_INIT(x...) printk(x)
#else
#define DBG_INIT(x...)
#endif
#ifdef DEBUG_CCIO_RUN
#define DBG_RUN(x...) printk(x)
#else
#define DBG_RUN(x...)
#endif
#ifdef DEBUG_CCIO_RES
#define DBG_RES(x...) printk(x)
#else
#define DBG_RES(x...)
#endif
#ifdef DEBUG_CCIO_RUN_SG
#define DBG_RUN_SG(x...) printk(x)
#else
#define DBG_RUN_SG(x...)
#endif
#define CCIO_INLINE inline
#define WRITE_U32(value, addr) __raw_writel(value, addr)
#define READ_U32(addr) __raw_readl(addr)
#define U2_IOA_RUNWAY 0x580
#define U2_BC_GSC 0x501
#define UTURN_IOA_RUNWAY 0x581
#define UTURN_BC_GSC 0x502
#define IOA_NORMAL_MODE 0x00020080 /* IO_CONTROL to turn on CCIO */
#define CMD_TLB_DIRECT_WRITE 35 /* IO_COMMAND for I/O TLB Writes */
#define CMD_TLB_PURGE 33 /* IO_COMMAND to Purge I/O TLB entry */
#define CCIO_MAPPING_ERROR (~(dma_addr_t)0)
struct ioa_registers {
/* Runway Supervisory Set */
int32_t unused1[12];
uint32_t io_command; /* Offset 12 */
uint32_t io_status; /* Offset 13 */
uint32_t io_control; /* Offset 14 */
int32_t unused2[1];
/* Runway Auxiliary Register Set */
uint32_t io_err_resp; /* Offset 0 */
uint32_t io_err_info; /* Offset 1 */
uint32_t io_err_req; /* Offset 2 */
uint32_t io_err_resp_hi; /* Offset 3 */
uint32_t io_tlb_entry_m; /* Off