code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_LCA__H__
#define __ALPHA_LCA__H__

#include <asm/compiler.h>
#include <asm/mce.h>

/*
 * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
 * for example).
 *
 * This file is based on:
 *
 *	DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
 *	Hardware Reference Manual; Digital Equipment Corp.; May 1994;
 *	Maynard, MA; Order Number: EC-N2681-71.
 */

/*
 * NOTE: The LCA uses a Host Address Extension (HAE) register to access
 *	 PCI addresses that are beyond the first 27 bits of address
 *	 space.  Updating the HAE requires an external cycle (and
 *	 a memory barrier), which tends to be slow.  Instead of updating
 *	 it on each sparse memory access, we keep the current HAE value
 *	 cached in variable cache_hae.  Only if the cached HAE differs
 *	 from the desired HAE value do we actually updated HAE register.
 *	 The HAE register is preserved by the interrupt handler entry/exit
 *	 code, so this scheme works even in the presence of interrupts.
 *
 * Dense memory space doesn't require the HAE, but is restricted to
 * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
 * Acknowledge cycles may also require the use of the HAE.  The LCA
 * limits I/O address space to the bottom 24 bits of address space,
 * but this easily covers the 16 bit ISA I/O address space.
 */

/*
 * NOTE 2! The memory operations do not set any memory barriers, as
 * it's not needed for cases like a frame buffer that is essentially
 * memory-like.  You need to do them by hand if the operations depend
 * on ordering.
 *
 * Similarly, the port I/O operations do a "mb" only after a write
 * operation: if an mb is needed before (as in the case of doing
 * memory mapped I/O first, and then a port I/O operation to the same
 * device), it needs to be done by hand.
 *
 * After the above has bitten me 100 times, I'll give up and just do
 * the mb all the time, but right now I'm hoping this will work out.
 * Avoiding mb's may potentially be a noticeable speed improvement,
 * but I can't honestly say I've tested it.
 *
 * Handling interrupts that need to do mb's to synchronize to
 * non-interrupts is another fun race area.  Don't do it (because if
 * you do, I'll have to do *everything* with interrupts disabled,
 * ugh).
 */

/*
 * Memory Controller registers:
 */
#define LCA_MEM_BCR0		(IDENT_ADDR + 0x120000000UL)
#define LCA_MEM_BCR1		(IDENT_ADDR + 0x120000008UL)
#define LCA_MEM_BCR2		(IDENT_ADDR + 0x120000010UL)
#define LCA_MEM_BCR3		(IDENT_ADDR + 0x120000018UL)
#define LCA_MEM_BMR0		(IDENT_ADDR + 0x120000020UL)
#define LCA_MEM_BMR1		(IDENT_ADDR + 0x120000028UL)
#define LCA_MEM_BMR2		(IDENT_ADDR + 0x120000030UL)
#define LCA_MEM_BMR3		(IDENT_ADDR + 0x120000038UL)
#define LCA_MEM_BTR0		(IDENT_ADDR + 0x120000040UL)
#define LCA_MEM_BTR1		(IDENT_ADDR + 0x120000048UL)
#define LCA_MEM_BTR2		(IDENT_ADDR + 0x120000050UL)
#define LCA_MEM_BTR3		(IDENT_ADDR + 0x120000058UL)
#define LCA_MEM_GTR		(IDENT_ADDR + 0x120000060UL)
#define LCA_MEM_ESR		(IDENT_ADDR + 0x120000068UL)
#define LCA_MEM_EAR		(IDENT_ADDR + 0x120000070UL)
#define LCA_MEM_CAR		(IDENT_ADDR + 0x120000078UL)
#define LCA_MEM_VGR		(IDENT_ADDR + 0x120000080UL)
#define LCA_MEM_PLM		(IDENT_ADDR + 0x120000088UL)
#define LCA_MEM_FOR		(IDENT_ADDR + 0x120000090UL)

/*
 * I/O Controller registers:
 */
#define LCA_IOC_HAE		(IDENT_ADDR + 0x180000000UL)
#define LCA_IOC_CONF		(IDENT_ADDR + 0x180000020UL)
#define LCA_IOC_STAT0		(IDENT_ADDR + 0x180000040UL)
#define LCA_IOC_STAT1		(IDENT_ADDR + 0x180000060UL)
#define LCA_IOC_TBIA		(IDENT_ADDR + 0x180000080UL)
#define LCA_IOC_TB_ENA		(IDENT_ADDR + 0x1800000a0UL)
#define LCA_IOC_SFT_RST		(IDENT_ADDR + 0x1800000c0UL)
#define LCA_IOC_PAR_DIS		(IDENT_ADDR + 0x1800000e0UL)
#define LCA_IOC_W_BASE0		(IDENT_ADDR + 0x180000100UL)
#define LCA_IOC_W_BASE1		(IDENT_ADDR + 0x180000120UL)
#define LCA_IOC_W_MASK0		(IDENT_ADDR + 0x180000140UL)
#define LCA_IOC_W_MASK1		(IDENT_ADDR + 0x180000160UL)
#define LCA_IOC_T_BASE0		(IDENT_ADDR + 0x180000180UL)
#define LCA_IOC_T_BASE1		(IDENT_ADDR + 0x1800001a0UL)
#define LCA_IOC_TB_TAG0		(IDENT_ADDR + 0x188000000UL)
#define LCA_IOC_TB_TAG1		(IDENT_ADDR + 0x188000020UL)
#define LCA_IOC_TB_TAG2		(IDENT_ADDR + 0x188000040UL)
#define LCA_IOC_TB_TAG3		(IDENT_ADDR + 0x188000060UL)
#define LCA_IOC_TB_TAG4		(IDENT_ADDR + 0x188000070UL)
#define LCA_IOC_TB_TAG5		(IDENT_ADDR + 0x1880000a0UL)
#define LCA_IOC_TB_TAG6		(IDENT_ADDR + 0x1880000c0UL)
#define LCA_IOC_TB_TAG7		(IDENT_ADDR + 0x1880000e0UL)

/*
 * Memory spaces:
 */
#define LCA_IACK_SC		(IDENT_ADDR + 0x1a0000000UL)
#define LCA_CONF		(IDENT_ADDR + 0x1e0000000UL)
#define LCA_IO			(IDENT_ADDR + 0x1c0000000UL)
#define LCA_SPARSE_MEM		(IDENT_ADDR + 0x200000000UL)
#define LCA_DENSE_MEM		(IDENT_ADDR + 0x300000000UL)

/*
 * Bit definitions for I/O Controller status register 0:
 */
#define LCA_IOC_STAT0_CMD		0xf
#define LCA_IOC_STAT0_ERR		(1<<4)
#define LCA_IOC_STAT0_LOST		(1<<5)
#define LCA_IOC_STAT0_THIT		(1<<6)
#define LCA_IOC_STAT0_TREF		(1<<7)
#define LCA_IOC_STAT0_CODE_SHIFT	8
#define LCA_IOC_STAT0_CODE_MASK		0x7
#define LCA_IOC_STAT0_P_NBR_SHIFT	13
#define LCA_IOC_STAT0_P_NBR_MASK	0x7ffff

#define LCA_HAE_ADDRESS		LCA_IOC_HAE

/* LCA PMR Power Management register defines */
#define LCA_PMR_ADDR	(IDENT_ADDR + 0x120000098UL)
#define LCA_PMR_PDIV    0x7                     /* Primary clock divisor */
#define LCA_PMR_ODIV    0x38                    /* Override clock divisor */
#define LCA_PMR_INTO    0x40                    /* Interrupt override */
#define LCA_PMR_DMAO    0x80                    /* DMA override */
#define LCA_PMR_OCCEB   0xffff0000L             /* Override cycle counter - even bits */
#define LCA_PMR_OCCOB   0xffff000000000000L     /* Override cycle counter - even bits */
#define LCA_PMR_PRIMARY_MASK    0xfffffffffffffff8L

/* LCA PMR Macros */

#define LCA_READ_PMR        (*(volatile unsigned long *)LCA_PMR_ADDR)
#define LCA_WRITE_PMR(d)    (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))

#define LCA_GET_PRIMARY(r)  ((r) & LCA_PMR_PDIV)
#define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
#define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))

/* LCA PMR Divisor values */
#define LCA_PMR_DIV_1   0x0
#define LCA_PMR_DIV_1_5 0x1
#define LCA_PMR_DIV_2   0x2
#define LCA_PMR_DIV_4   0x3
#define LCA_PMR_DIV_8   0x4
#define LCA_PMR_DIV_16  0x5
#define LCA_PMR_DIV_MIN DIV_1
#define LCA_PMR_DIV_MAX DIV_16

/*
 * Data structure for handling LCA machine checks.  Correctable errors
 * result in a short logout frame, uncorrectable ones in a long one.
 */
struct el_lca_mcheck_short {
	struct el_common	h;		/* common logout header */
	unsigned long		esr;		/* error-status register */
	unsigned long		ear;		/* error-address register */
	unsigned long		dc_stat;	/* dcache status register */
	unsigned long		ioc_stat0;	/* I/O controller status register 0 */
	unsigned long		ioc_stat1;	/* I/O controller status register 1 */
};

struct el_lca_mcheck_long {
	struct el_common	h;		/* common logout header */
	unsigned long		pt[31];		/* PAL temps */
	unsigned long		exc_addr;	/* exception address */
	unsigned long		pad1[3];
	unsigned long		pal_base;	/* PALcode base address */
	unsigned long		hier;		/* hw interrupt enable */
	unsigned long		hirr;		/* hw interrupt request */
	unsigned long		mm_csr;		/* MMU control & status */
	unsigned long		dc_stat;	/* data cache status */
	unsigned long		dc_addr;	/* data cache addr register */
	unsigned long		abox_ctl;	/* address box control register */
	unsigned long		esr;		/* error status register */
	unsigned long		ear;		/* error address register */
	unsigned long		car;		/* cache control register */
	unsigned long		ioc_stat0;	/* I/O controller status register 0 */
	unsigned long		ioc_stat1;	/* I/O controller status register 1 */
	unsigned long		va;		/* virtual address register */
};

union el_lca {
	struct el_common *		c;
	struct el_lca_mcheck_long *	l;
	struct el_lca_mcheck_short *	s;
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * Unlike Jensen, the Noname machines have no concept of local
 * I/O---everything goes over the PCI bus.
 *
 * There is plenty room for optimization here.  In particular,
 * the Alpha's insb/insw/extb/extw should be useful in moving
 * data to/from the right byte-lanes.
 */

#define vip	volatile int __force *
#define vuip	volatile unsigned int __force *
#define vulp	volatile unsigned long __force *

#define LCA_SET_HAE						\
	do {							\
		if (addr >= (1UL << 24)) {			\
			unsigned long msb = addr & 0xf8000000;	\
			addr -= msb;				\
			set_hae(msb);				\
		}						\
	} while (0)

__EXTERN_INLINE u8 lca_ioread8(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	unsigned long result, base_and_type;

	if (addr >= LCA_DENSE_MEM) {
		addr -= LCA_DENSE_MEM;
		LCA_SET_HAE;
		base_and_type = LCA_SPARSE_MEM + 0x00;
	} else {
		addr -= LCA_IO;
		base_and_type = LCA_IO + 0x00;
	}

	result = *(vip) ((addr << 5) + base_and_type);
	return __kernel_extbl(result, addr & 3);
}

__EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	unsigned long w, base_and_type;

	if (addr >= LCA_DENSE_MEM) {
		addr -= LCA_DENSE_MEM;
		LCA_SET_HAE;
		base_and_type = LCA_SPARSE_MEM + 0x00;
	} else {
		addr -= LCA_IO;
		base_and_type = LCA_IO + 0x00;
	}

	w = __kernel_insbl(b, addr & 3);
	*(vuip) ((addr << 5) + base_and_type) = w;
}

__EXTERN_INLINE u16 lca_ioread16(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	unsigned long result, base_and_type;

	if (addr >= LCA_DENSE_MEM) {
		addr -= LCA_DENSE_MEM;
		LCA_SET_HAE;
		base_and_type = LCA_SPARSE_MEM + 0x08;
	} else {
		addr -= LCA_IO;
		base_and_type = LCA_IO + 0x08;
	}

	result = *(vip) ((addr << 5) + base_and_type);
	return __kernel_extwl(result, addr & 3);
}

__EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	unsigned long w, base_and_type;

	if (addr >= LCA_DENSE_MEM) {
		addr -= LCA_DENSE_MEM;
		LCA_SET_HAE;
		base_and_type = LCA_SPARSE_MEM + 0x08;
	} else {
		addr -= LCA_IO;
		base_and_type = LCA_IO + 0x08;
	}

	w = __kernel_inswl(b, addr & 3);
	*(vuip) ((addr << 5) + base_and_type) = w;
}

__EXTERN_INLINE u32 lca_ioread32(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	if (addr < LCA_DENSE_MEM)
		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
	return *(vuip)addr;
}

__EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	if (addr < LCA_DENSE_MEM)
		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
	*(vuip)addr = b;
}

__EXTERN_INLINE u64 lca_ioread64(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	if (addr < LCA_DENSE_MEM)
		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
	return *(vulp)addr;
}

__EXTERN_INLINE void lca_iowrite64(u64 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	if (addr < LCA_DENSE_MEM)
		addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
	*(vulp)addr = b;
}

__EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
{
	return (void __iomem *)(addr + LCA_IO);
}

__EXTERN_INLINE void __iomem *lca_ioremap(unsigned long addr,
					  unsigned long size)
{
	return (void __iomem *)(addr + LCA_DENSE_MEM);
}

__EXTERN_INLINE int lca_is_ioaddr(unsigned long addr)
{
	return addr >= IDENT_ADDR + 0x120000000UL;
}

__EXTERN_INLINE int lca_is_mmio(const volatile void __iomem *addr)
{
	return (unsigned long)addr >= LCA_DENSE_MEM;
}

#undef vip
#undef vuip
#undef vulp

#undef __IO_PREFIX
#define __IO_PREFIX		lca
#define lca_trivial_rw_bw	2
#define lca_trivial_rw_lq	1
#define lca_trivial_io_bw	0
#define lca_trivial_io_lq	0
#define lca_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_LCA__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access
 *
 * This file is based on:
 *
 * Marvel / EV7 System Programmer's Manual
 * Revision 1.00
 * 14 May 2001
 */

#ifndef __ALPHA_MARVEL__H__
#define __ALPHA_MARVEL__H__

#include <linux/types.h>
#include <linux/spinlock.h>

#include <asm/compiler.h>

#define MARVEL_MAX_PIDS		 32 /* as long as we rely on 43-bit superpage */
#define MARVEL_IRQ_VEC_PE_SHIFT	(10)
#define MARVEL_IRQ_VEC_IRQ_MASK	((1 << MARVEL_IRQ_VEC_PE_SHIFT) - 1)
#define MARVEL_NR_IRQS		\
	(16 + (MARVEL_MAX_PIDS * (1 << MARVEL_IRQ_VEC_PE_SHIFT)))

/*
 * EV7 RBOX Registers
 */
typedef struct {
	volatile unsigned long csr __attribute__((aligned(16)));
} ev7_csr;

typedef struct {
	ev7_csr	RBOX_CFG;		/* 0x0000 */
	ev7_csr	RBOX_NSVC;
	ev7_csr	RBOX_EWVC;
	ev7_csr	RBOX_WHAMI;
	ev7_csr	RBOX_TCTL;		/* 0x0040 */
	ev7_csr	RBOX_INT;
	ev7_csr	RBOX_IMASK;
	ev7_csr	RBOX_IREQ;
	ev7_csr	RBOX_INTQ;		/* 0x0080 */
	ev7_csr	RBOX_INTA;
	ev7_csr	RBOX_IT;
	ev7_csr	RBOX_SCRATCH1;
	ev7_csr	RBOX_SCRATCH2;		/* 0x00c0 */
	ev7_csr	RBOX_L_ERR;
} ev7_csrs;

/*
 * EV7 CSR addressing macros
 */
#define EV7_MASK40(addr)        ((addr) & ((1UL << 41) - 1))
#define EV7_KERN_ADDR(addr)	((void *)(IDENT_ADDR | EV7_MASK40(addr)))

#define EV7_PE_MASK		0x1ffUL /* 9 bits ( 256 + mem/io ) */
#define EV7_IPE(pe)		((~((long)(pe)) & EV7_PE_MASK) << 35)

#define EV7_CSR_PHYS(pe, off)	(EV7_IPE(pe) | (0x7FFCUL << 20) | (off))
#define EV7_CSRS_PHYS(pe)	(EV7_CSR_PHYS(pe, 0UL))

#define EV7_CSR_KERN(pe, off)	(EV7_KERN_ADDR(EV7_CSR_PHYS(pe, off)))
#define EV7_CSRS_KERN(pe)	(EV7_KERN_ADDR(EV7_CSRS_PHYS(pe)))

#define EV7_CSR_OFFSET(name)	((unsigned long)&((ev7_csrs *)NULL)->name.csr)

/*
 * IO7 registers
 */
typedef struct {
	volatile unsigned long csr __attribute__((aligned(64)));
} io7_csr;

typedef struct {
	/* I/O Port Control Registers */
	io7_csr	POx_CTRL;	       	/* 0x0000 */
	io7_csr	POx_CACHE_CTL;
	io7_csr POx_TIMER;
	io7_csr POx_IO_ADR_EXT;
	io7_csr	POx_MEM_ADR_EXT;	/* 0x0100 */
	io7_csr POx_XCAL_CTRL;
	io7_csr rsvd1[2];	/* ?? spec doesn't show 0x180 */
	io7_csr POx_DM_SOURCE;		/* 0x0200 */
	io7_csr POx_DM_DEST;
	io7_csr POx_DM_SIZE;
	io7_csr POx_DM_CTRL;
	io7_csr rsvd2[4];		/* 0x0300 */

	/* AGP Control Registers -- port 3 only */
	io7_csr AGP_CAP_ID;		/* 0x0400 */
	io7_csr AGP_STAT;
	io7_csr	AGP_CMD;
	io7_csr	rsvd3;

	/* I/O Port Monitor Registers */
	io7_csr	POx_MONCTL;		/* 0x0500 */
	io7_csr POx_CTRA;
	io7_csr POx_CTRB;
	io7_csr POx_CTR56;
	io7_csr POx_SCRATCH;		/* 0x0600 */
	io7_csr POx_XTRA_A;
	io7_csr POx_XTRA_TS;
	io7_csr POx_XTRA_Z;
	io7_csr rsvd4;			/* 0x0700 */
	io7_csr POx_THRESHA;
	io7_csr POx_THRESHB;
	io7_csr rsvd5[33];

	/* System Address Space Window Control Registers */

	io7_csr POx_WBASE[4];		/* 0x1000 */
	io7_csr POx_WMASK[4];
	io7_csr POx_TBASE[4];
	io7_csr POx_SG_TBIA;
	io7_csr POx_MSI_WBASE;
	io7_csr rsvd6[50];

	/* I/O Port Error Registers */
	io7_csr POx_ERR_SUM;
	io7_csr POx_FIRST_ERR;
	io7_csr POx_MSK_HEI;
	io7_csr POx_TLB_ERR;
	io7_csr POx_SPL_COMPLT;
	io7_csr POx_TRANS_SUM;
	io7_csr POx_FRC_PCI_ERR;
	io7_csr POx_MULT_ERR;
	io7_csr rsvd7[8];

	/* I/O Port End of Interrupt Registers */
	io7_csr EOI_DAT;
	io7_csr rsvd8[7];
	io7_csr POx_IACK_SPECIAL;
	io7_csr rsvd9[103];
} io7_ioport_csrs;

typedef struct {
	io7_csr IO_ASIC_REV;		/* 0x30.0000 */
	io7_csr IO_SYS_REV;
	io7_csr SER_CHAIN3;
	io7_csr PO7_RST1;
	io7_csr PO7_RST2;		/* 0x30.0100 */
	io7_csr POx_RST[4];
	io7_csr IO7_DWNH;
	io7_csr IO7_MAF;
	io7_csr IO7_MAF_TO;
	io7_csr IO7_ACC_CLUMP;		/* 0x30.0300 */
	io7_csr IO7_PMASK;
	io7_csr IO7_IOMASK;
	io7_csr IO7_UPH;
	io7_csr IO7_UPH_TO;		/* 0x30.0400 */
	io7_csr RBX_IREQ_OFF;
	io7_csr RBX_INTA_OFF;
	io7_csr INT_RTY;
	io7_csr PO7_MONCTL;		/* 0x30.0500 */
	io7_csr PO7_CTRA;
	io7_csr PO7_CTRB;
	io7_csr PO7_CTR56;
	io7_csr PO7_SCRATCH;		/* 0x30.0600 */
	io7_csr PO7_XTRA_A;
	io7_csr PO7_XTRA_TS;
	io7_csr PO7_XTRA_Z;
	io7_csr PO7_PMASK;		/* 0x30.0700 */
	io7_csr PO7_THRESHA;
	io7_csr PO7_THRESHB;
	io7_csr rsvd1[97];
	io7_csr PO7_ERROR_SUM;		/* 0x30.2000 */
	io7_csr PO7_BHOLE_MASK;
	io7_csr PO7_HEI_MSK;
	io7_csr PO7_CRD_MSK;
	io7_csr PO7_UNCRR_SYM;		/* 0x30.2100 */
	io7_csr PO7_CRRCT_SYM;
	io7_csr PO7_ERR_PKT[2];
	io7_csr PO7_UGBGE_SYM;		/* 0x30.2200 */
	io7_csr rsbv2[887];
	io7_csr PO7_LSI_CTL[128];	/* 0x31.0000 */
	io7_csr rsvd3[123];
	io7_csr HLT_CTL;		/* 0x31.3ec0 */
	io7_csr HPI_CTL;		/* 0x31.3f00 */
	io7_csr CRD_CTL;
	io7_csr STV_CTL;
	io7_csr HEI_CTL;
	io7_csr PO7_MSI_CTL[16];	/* 0x31.4000 */
	io7_csr rsvd4[240];

	/*
	 * Interrupt Diagnostic / Test
	 */
	struct {
		io7_csr INT_PND;
		io7_csr INT_CLR;
		io7_csr INT_EOI;
		io7_csr rsvd[29];
	} INT_DIAG[4];
	io7_csr rsvd5[125];	    	/* 0x31.a000 */
	io7_csr MISC_PND;		/* 0x31.b800 */
	io7_csr rsvd6[31];
	io7_csr MSI_PND[16];		/* 0x31.c000 */
	io7_csr rsvd7[16];
	io7_csr MSI_CLR[16];		/* 0x31.c800 */
} io7_port7_csrs;

/*
 * IO7 DMA Window Base register (POx_WBASEx)
 */
#define wbase_m_ena  0x1
#define wbase_m_sg   0x2
#define wbase_m_dac  0x4
#define wbase_m_addr 0xFFF00000
union IO7_POx_WBASE {
	struct {
		unsigned ena : 1;	/* <0>			*/
		unsigned sg : 1;	/* <1>			*/
		unsigned dac : 1;	/* <2> -- window 3 only */
		unsigned rsvd1 : 17;
		unsigned addr : 12;	/* <31:20>		*/
		unsigned rsvd2 : 32;
	} bits;
	unsigned as_long[2];
	unsigned as_quad;
};

/*
 * IO7 IID (Interrupt IDentifier) format
 *
 * For level-sensative interrupts, int_num is encoded as:
 *
 *	bus/port	slot/device	INTx
 *	<7:5>		<4:2>		<1:0>
 */
union IO7_IID {
	struct {
		unsigned int_num : 9;		/* <8:0>    	*/
		unsigned tpu_mask : 4;		/* <12:9> rsvd	*/
		unsigned msi : 1;		/* 13		*/
		unsigned ipe : 10;		/* <23:14>	*/
		unsigned long rsvd : 40;
	} bits;
	unsigned int as_long[2];
	unsigned long as_quad;
};

/*
 * IO7 addressing macros
 */
#define IO7_KERN_ADDR(addr)	(EV7_KERN_ADDR(addr))

#define IO7_PORT_MASK	   	0x07UL	/* 3 bits of port 	   */

#define IO7_IPE(pe)		(EV7_IPE(pe))
#define IO7_IPORT(port)		((~((long)(port)) & IO7_PORT_MASK) << 32)

#define IO7_HOSE(pe, port)	(IO7_IPE(pe) | IO7_IPORT(port))

#define IO7_MEM_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0x00000000UL)
#define IO7_CONF_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0xFE000000UL)
#define IO7_IO_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0xFF000000UL)
#define IO7_CSR_PHYS(pe, port, off) \
                                (IO7_HOSE(pe, port) | 0xFF800000UL | (off))
#define IO7_CSRS_PHYS(pe, port)	(IO7_CSR_PHYS(pe, port, 0UL))
#define IO7_PORT7_CSRS_PHYS(pe) (IO7_CSR_PHYS(pe, 7, 0x300000UL))

#define IO7_MEM_KERN(pe, port)      (IO7_KERN_ADDR(IO7_MEM_PHYS(pe, port)))
#define IO7_CONF_KERN(pe, port)     (IO7_KERN_ADDR(IO7_CONF_PHYS(pe, port)))
#define IO7_IO_KERN(pe, port)       (IO7_KERN_ADDR(IO7_IO_PHYS(pe, port)))
#define IO7_CSR_KERN(pe, port, off) (IO7_KERN_ADDR(IO7_CSR_PHYS(pe,port,off)))
#define IO7_CSRS_KERN(pe, port)     (IO7_KERN_ADDR(IO7_CSRS_PHYS(pe, port)))
#define IO7_PORT7_CSRS_KERN(pe)	    (IO7_KERN_ADDR(IO7_PORT7_CSRS_PHYS(pe)))

#define IO7_PLL_RNGA(pll)	(((pll) >> 3) & 0x7)
#define IO7_PLL_RNGB(pll)	(((pll) >> 6) & 0x7)

#define IO7_MEM_SPACE		(2UL * 1024 * 1024 * 1024)	/* 2GB MEM */
#define IO7_IO_SPACE		(8UL * 1024 * 1024)		/* 8MB I/O */

/*
 * Offset between ram physical addresses and pci64 DAC addresses
 */
#define IO7_DAC_OFFSET		(1UL << 49)

/*
 * This is needed to satisify the IO() macro used in initializing the machvec
 */
#define MARVEL_IACK_SC 							\
        ((unsigned long)						\
	 (&(((io7_ioport_csrs *)IO7_CSRS_KERN(0, 0))->POx_IACK_SPECIAL)))

#ifdef __KERNEL__

/*
 * IO7 structs
 */
#define IO7_NUM_PORTS 4
#define IO7_AGP_PORT  3

struct io7_port {
	struct io7 *io7;
	struct pci_controller *hose;

	int enabled;
	unsigned int port;
	io7_ioport_csrs *csrs;

	unsigned long saved_wbase[4];
	unsigned long saved_wmask[4];
	unsigned long saved_tbase[4];
};

struct io7 {
	struct io7 *next;

	unsigned int pe;
	io7_port7_csrs *csrs;
	struct io7_port ports[IO7_NUM_PORTS];

	raw_spinlock_t irq_lock;
};

#ifndef __EXTERN_INLINE
# define __EXTERN_INLINE extern inline
# define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions. All access through linear space.
 */

/*
 * Memory functions.  All accesses through linear space.
 */

#define vucp	volatile unsigned char __force *
#define vusp	volatile unsigned short __force *

extern u8 marvel_ioread8(const void __iomem *);
extern void marvel_iowrite8(u8 b, void __iomem *);

__EXTERN_INLINE u16 marvel_ioread16(const void __iomem *addr)
{
	return __kernel_ldwu(*(vusp)addr);
}

__EXTERN_INLINE void marvel_iowrite16(u16 b, void __iomem *addr)
{
	__kernel_stw(b, *(vusp)addr);
}

extern void __iomem *marvel_ioremap(unsigned long addr, unsigned long size);
extern void marvel_iounmap(volatile void __iomem *addr);
extern void __iomem *marvel_ioportmap (unsigned long addr);

__EXTERN_INLINE int marvel_is_ioaddr(unsigned long addr)
{
	return (addr >> 40) & 1;
}

extern int marvel_is_mmio(const volatile void __iomem *);

#undef vucp
#undef vusp

#undef __IO_PREFIX
#define __IO_PREFIX		marvel
#define marvel_trivial_rw_bw	1
#define marvel_trivial_rw_lq	1
#define marvel_trivial_io_bw	0
#define marvel_trivial_io_lq	1
#define marvel_trivial_iounmap	0
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
# undef __EXTERN_INLINE
# undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_MARVEL__H__ */

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_MCPCIA__H__
#define __ALPHA_MCPCIA__H__

/* Define to experiment with fitting everything into one 128MB HAE window.
   One window per bus, that is.  */
#define MCPCIA_ONE_HAE_WINDOW 1

#include <linux/types.h>
#include <asm/compiler.h>
#include <asm/mce.h>

/*
 * MCPCIA is the internal name for a core logic chipset which provides
 * PCI access for the RAWHIDE family of systems.
 *
 * This file is based on:
 *
 * RAWHIDE System Programmer's Manual
 * 16-May-96
 * Rev. 1.4
 *
 */

/*------------------------------------------------------------------------**
**                                                                        **
**  I/O procedures                                                        **
**                                                                        **
**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
**	inportbxt: 8 bits only                                            **
**      inport:    alias of inportw                                       **
**      outport:   alias of outportw                                      **
**                                                                        **
**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
**	inmembxt: 8 bits only                                             **
**      inmem:    alias of inmemw                                         **
**      outmem:   alias of outmemw                                        **
**                                                                        **
**------------------------------------------------------------------------*/

/* MCPCIA ADDRESS BIT DEFINITIONS
 *
 *  3333 3333 3322 2222 2222 1111 1111 11
 *  9876 5432 1098 7654 3210 9876 5432 1098 7654 3210
 *  ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
 *  1                                             000
 *  ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
 *  |                                             |\|
 *  |                               Byte Enable --+ |
 *  |                             Transfer Length --+
 *  +-- IO space, not cached
 *
 *   Byte      Transfer
 *   Enable    Length    Transfer  Byte    Address
 *   adr<6:5>  adr<4:3>  Length    Enable  Adder
 *   ---------------------------------------------
 *      00        00      Byte      1110   0x000
 *      01        00      Byte      1101   0x020
 *      10        00      Byte      1011   0x040
 *      11        00      Byte      0111   0x060
 *
 *      00        01      Word      1100   0x008
 *      01        01      Word      1001   0x028 <= Not supported in this code.
 *      10        01      Word      0011   0x048
 *
 *      00        10      Tribyte   1000   0x010
 *      01        10      Tribyte   0001   0x030
 *
 *      10        11      Longword  0000   0x058
 *
 *      Note that byte enables are asserted low.
 *
 */

#define MCPCIA_MAX_HOSES 4

#define MCPCIA_MID(m)		((unsigned long)(m) << 33)

/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively.
   Durango adds PCI2 and PCI3 at MID 6 and 7 respectively.  */
#define MCPCIA_HOSE2MID(h)	((h) + 4)

#define MCPCIA_MEM_MASK 0x07ffffff /* SPARSE Mem region mask is 27 bits */

/*
 * Memory spaces:
 */
#define MCPCIA_SPARSE(m)	(IDENT_ADDR + 0xf000000000UL + MCPCIA_MID(m))
#define MCPCIA_DENSE(m)		(IDENT_ADDR + 0xf100000000UL + MCPCIA_MID(m))
#define MCPCIA_IO(m)		(IDENT_ADDR + 0xf180000000UL + MCPCIA_MID(m))
#define MCPCIA_CONF(m)		(IDENT_ADDR + 0xf1c0000000UL + MCPCIA_MID(m))
#define MCPCIA_CSR(m)		(IDENT_ADDR + 0xf1e0000000UL + MCPCIA_MID(m))
#define MCPCIA_IO_IACK(m)	(IDENT_ADDR + 0xf1f0000000UL + MCPCIA_MID(m))
#define MCPCIA_DENSE_IO(m)	(IDENT_ADDR + 0xe1fc000000UL + MCPCIA_MID(m))
#define MCPCIA_DENSE_CONF(m)	(IDENT_ADDR + 0xe1fe000000UL + MCPCIA_MID(m))

/*
 *  General Registers
 */
#define MCPCIA_REV(m)		(MCPCIA_CSR(m) + 0x000)
#define MCPCIA_WHOAMI(m)	(MCPCIA_CSR(m) + 0x040)
#define MCPCIA_PCI_LAT(m)	(MCPCIA_CSR(m) + 0x080)
#define MCPCIA_CAP_CTRL(m)	(MCPCIA_CSR(m) + 0x100)
#define MCPCIA_HAE_MEM(m)	(MCPCIA_CSR(m) + 0x400)
#define MCPCIA_HAE_IO(m)	(MCPCIA_CSR(m) + 0x440)
#define _MCPCIA_IACK_SC(m)	(MCPCIA_CSR(m) + 0x480)
#define MCPCIA_HAE_DENSE(m)	(MCPCIA_CSR(m) + 0x4C0)

/*
 * Interrupt Control registers
 */
#define MCPCIA_INT_CTL(m)	(MCPCIA_CSR(m) + 0x500)
#define MCPCIA_INT_REQ(m)	(MCPCIA_CSR(m) + 0x540)
#define MCPCIA_INT_TARG(m)	(MCPCIA_CSR(m) + 0x580)
#define MCPCIA_INT_ADR(m)	(MCPCIA_CSR(m) + 0x5C0)
#define MCPCIA_INT_ADR_EXT(m)	(MCPCIA_CSR(m) + 0x600)
#define MCPCIA_INT_MASK0(m)	(MCPCIA_CSR(m) + 0x640)
#define MCPCIA_INT_MASK1(m)	(MCPCIA_CSR(m) + 0x680)
#define MCPCIA_INT_ACK0(m)	(MCPCIA_CSR(m) + 0x10003f00)
#define MCPCIA_INT_ACK1(m)	(MCPCIA_CSR(m) + 0x10003f40)

/*
 * Performance Monitor registers
 */
#define MCPCIA_PERF_MON(m)	(MCPCIA_CSR(m) + 0x300)
#define MCPCIA_PERF_CONT(m)	(MCPCIA_CSR(m) + 0x340)

/*
 * Diagnostic Registers
 */
#define MCPCIA_CAP_DIAG(m)	(MCPCIA_CSR(m) + 0x700)
#define MCPCIA_TOP_OF_MEM(m)	(MCPCIA_CSR(m) + 0x7C0)

/*
 * Error registers
 */
#define MCPCIA_MC_ERR0(m)	(MCPCIA_CSR(m) + 0x800)
#define MCPCIA_MC_ERR1(m)	(MCPCIA_CSR(m) + 0x840)
#define MCPCIA_CAP_ERR(m)	(MCPCIA_CSR(m) + 0x880)
#define MCPCIA_PCI_ERR1(m)	(MCPCIA_CSR(m) + 0x1040)
#define MCPCIA_MDPA_STAT(m)	(MCPCIA_CSR(m) + 0x4000)
#define MCPCIA_MDPA_SYN(m)	(MCPCIA_CSR(m) + 0x4040)
#define MCPCIA_MDPA_DIAG(m)	(MCPCIA_CSR(m) + 0x4080)
#define MCPCIA_MDPB_STAT(m)	(MCPCIA_CSR(m) + 0x8000)
#define MCPCIA_MDPB_SYN(m)	(MCPCIA_CSR(m) + 0x8040)
#define MCPCIA_MDPB_DIAG(m)	(MCPCIA_CSR(m) + 0x8080)

/*
 * PCI Address Translation Registers.
 */
#define MCPCIA_SG_TBIA(m)	(MCPCIA_CSR(m) + 0x1300)
#define MCPCIA_HBASE(m)		(MCPCIA_CSR(m) + 0x1340)

#define MCPCIA_W0_BASE(m)	(MCPCIA_CSR(m) + 0x1400)
#define MCPCIA_W0_MASK(m)	(MCPCIA_CSR(m) + 0x1440)
#define MCPCIA_T0_BASE(m)	(MCPCIA_CSR(m) + 0x1480)

#define MCPCIA_W1_BASE(m)	(MCPCIA_CSR(m) + 0x1500)
#define MCPCIA_W1_MASK(m)	(MCPCIA_CSR(m) + 0x1540)
#define MCPCIA_T1_BASE(m)	(MCPCIA_CSR(m) + 0x1580)

#define MCPCIA_W2_BASE(m)	(MCPCIA_CSR(m) + 0x1600)
#define MCPCIA_W2_MASK(m)	(MCPCIA_CSR(m) + 0x1640)
#define MCPCIA_T2_BASE(m)	(MCPCIA_CSR(m) + 0x1680)

#define MCPCIA_W3_BASE(m)	(MCPCIA_CSR(m) + 0x1700)
#define MCPCIA_W3_MASK(m)	(MCPCIA_CSR(m) + 0x1740)
#define MCPCIA_T3_BASE(m)	(MCPCIA_CSR(m) + 0x1780)

/* Hack!  Only words for bus 0.  */

#ifndef MCPCIA_ONE_HAE_WINDOW
#define MCPCIA_HAE_ADDRESS	MCPCIA_HAE_MEM(4)
#endif
#define MCPCIA_IACK_SC		_MCPCIA_IACK_SC(4)

/*
 * The canonical non-remaped I/O and MEM addresses have these values
 * subtracted out.  This is arranged so that folks manipulating ISA
 * devices can use their familiar numbers and have them map to bus 0.
 */

#define MCPCIA_IO_BIAS		MCPCIA_IO(4)
#define MCPCIA_MEM_BIAS		MCPCIA_DENSE(4)

/* Offset between ram physical addresses and pci64 DAC bus addresses.  */
#define MCPCIA_DAC_OFFSET	(1UL << 40)

/*
 * Data structure for handling MCPCIA machine checks:
 */
struct el_MCPCIA_uncorrected_frame_mcheck {
	struct el_common header;
	struct el_common_EV5_uncorrectable_mcheck procdata;
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * MCPCIA, the RAWHIDE family PCI/memory support chipset for the EV5 (21164)
 * and EV56 (21164a) processors, can use either a sparse address mapping
 * scheme, or the so-called byte-word PCI address space, to get at PCI memory
 * and I/O.
 *
 * Unfortunately, we can't use BWIO with EV5, so for now, we always use SPARSE.
 */

/*
 * Memory functions.  64-bit and 32-bit accesses are done through
 * dense memory space, everything else through sparse space.
 *
 * For reading and writing 8 and 16 bit quantities we need to
 * go through one of the three sparse address mapping regions
 * and use the HAE_MEM CSR to provide some bits of the address.
 * The following few routines use only sparse address region 1
 * which gives 1Gbyte of accessible space which relates exactly
 * to the amount of PCI memory mapping *into* system address space.
 * See p 6-17 of the specification but it looks something like this:
 *
 * 21164 Address:
 *
 *          3         2         1
 * 9876543210987654321098765432109876543210
 * 1ZZZZ0.PCI.QW.Address............BBLL
 *
 * ZZ = SBZ
 * BB = Byte offset
 * LL = Transfer length
 *
 * PCI Address:
 *
 * 3         2         1
 * 10987654321098765432109876543210
 * HHH....PCI.QW.Address........ 00
 *
 * HHH = 31:29 HAE_MEM CSR
 *
 */

#define vip	volatile int __force *
#define vuip	volatile unsigned int __force *
#define vulp	volatile unsigned long __force *

#ifndef MCPCIA_ONE_HAE_WINDOW
#define MCPCIA_FROB_MMIO						\
	if (__mcpcia_is_mmio(hose)) {					\
		set_hae(hose & 0xffffffff);				\
		hose = hose - MCPCIA_DENSE(4) + MCPCIA_SPARSE(4);	\
	}
#else
#define MCPCIA_FROB_MMIO						\
	if (__mcpcia_is_mmio(hose)) {					\
		hose = hose - MCPCIA_DENSE(4) + MCPCIA_SPARSE(4);	\
	}
#endif

extern inline int __mcpcia_is_mmio(unsigned long addr)
{
	return (addr & 0x80000000UL) == 0;
}

__EXTERN_INLINE u8 mcpcia_ioread8(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
	unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
	unsigned long result;

	MCPCIA_FROB_MMIO;

	result = *(vip) ((addr << 5) + hose + 0x00);
	return __kernel_extbl(result, addr & 3);
}

__EXTERN_INLINE void mcpcia_iowrite8(u8 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
	unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
	unsigned long w;

	MCPCIA_FROB_MMIO;

	w = __kernel_insbl(b, addr & 3);
	*(vuip) ((addr << 5) + hose + 0x00) = w;
}

__EXTERN_INLINE u16 mcpcia_ioread16(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
	unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
	unsigned long result;

	MCPCIA_FROB_MMIO;

	result = *(vip) ((addr << 5) + hose + 0x08);
	return __kernel_extwl(result, addr & 3);
}

__EXTERN_INLINE void mcpcia_iowrite16(u16 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
	unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
	unsigned long w;

	MCPCIA_FROB_MMIO;

	w = __kernel_inswl(b, addr & 3);
	*(vuip) ((addr << 5) + hose + 0x08) = w;
}

__EXTERN_INLINE u32 mcpcia_ioread32(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr;

	if (!__mcpcia_is_mmio(addr))
		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;

	return *(vuip)addr;
}

__EXTERN_INLINE void mcpcia_iowrite32(u32 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr;

	if (!__mcpcia_is_mmio(addr))
		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;

	*(vuip)addr = b;
}

__EXTERN_INLINE u64 mcpcia_ioread64(const void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr;

	if (!__mcpcia_is_mmio(addr))
		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;

	return *(vulp)addr;
}

__EXTERN_INLINE void mcpcia_iowrite64(u64 b, void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr;

	if (!__mcpcia_is_mmio(addr))
		addr = ((addr & 0xffff) << 5) + (addr & ~0xfffful) + 0x18;

	*(vulp)addr = b;
}

__EXTERN_INLINE void __iomem *mcpcia_ioportmap(unsigned long addr)
{
	return (void __iomem *)(addr + MCPCIA_IO_BIAS);
}

__EXTERN_INLINE void __iomem *mcpcia_ioremap(unsigned long addr,
					     unsigned long size)
{
	return (void __iomem *)(addr + MCPCIA_MEM_BIAS);
}

__EXTERN_INLINE int mcpcia_is_ioaddr(unsigned long addr)
{
	return addr >= MCPCIA_SPARSE(0);
}

__EXTERN_INLINE int mcpcia_is_mmio(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	return __mcpcia_is_mmio(addr);
}

#undef MCPCIA_FROB_MMIO

#undef vip
#undef vuip
#undef vulp

#undef __IO_PREFIX
#define __IO_PREFIX		mcpcia
#define mcpcia_trivial_rw_bw	2
#define mcpcia_trivial_rw_lq	1
#define mcpcia_trivial_io_bw	0
#define mcpcia_trivial_io_lq	0
#define mcpcia_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_MCPCIA__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_POLARIS__H__
#define __ALPHA_POLARIS__H__

#include <linux/types.h>
#include <asm/compiler.h>

/*
 * POLARIS is the internal name for a core logic chipset which provides
 * memory controller and PCI access for the 21164PC chip based systems.
 *
 * This file is based on:
 *
 * Polaris System Controller
 * Device Functional Specification
 * 22-Jan-98
 * Rev. 4.2
 *
 */

/* Polaris memory regions */
#define POLARIS_SPARSE_MEM_BASE		(IDENT_ADDR + 0xf800000000UL)
#define POLARIS_DENSE_MEM_BASE		(IDENT_ADDR + 0xf900000000UL)
#define POLARIS_SPARSE_IO_BASE		(IDENT_ADDR + 0xf980000000UL)
#define POLARIS_SPARSE_CONFIG_BASE	(IDENT_ADDR + 0xf9c0000000UL)
#define POLARIS_IACK_BASE		(IDENT_ADDR + 0xf9f8000000UL)
#define POLARIS_DENSE_IO_BASE		(IDENT_ADDR + 0xf9fc000000UL)
#define POLARIS_DENSE_CONFIG_BASE	(IDENT_ADDR + 0xf9fe000000UL)

#define POLARIS_IACK_SC			POLARIS_IACK_BASE

/* The Polaris command/status registers live in PCI Config space for
 * bus 0/device 0.  As such, they may be bytes, words, or doublewords.
 */
#define POLARIS_W_VENID		(POLARIS_DENSE_CONFIG_BASE)
#define POLARIS_W_DEVID		(POLARIS_DENSE_CONFIG_BASE+2)
#define POLARIS_W_CMD		(POLARIS_DENSE_CONFIG_BASE+4)
#define POLARIS_W_STATUS	(POLARIS_DENSE_CONFIG_BASE+6)

/*
 * Data structure for handling POLARIS machine checks:
 */
struct el_POLARIS_sysdata_mcheck {
    u_long      psc_status;
    u_long	psc_pcictl0;
    u_long	psc_pcictl1;
    u_long	psc_pcictl2;
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * POLARIS, the PCI/memory support chipset for the PCA56 (21164PC)
 * processors, can use either a sparse address  mapping scheme, or the
 * so-called byte-word PCI address space, to get at PCI memory and I/O.
 *
 * However, we will support only the BWX form.
 */

/*
 * Memory functions.  Polaris allows all accesses (byte/word
 * as well as long/quad) to be done through dense space.
 *
 * We will only support DENSE access via BWX insns.
 */

__EXTERN_INLINE void __iomem *polaris_ioportmap(unsigned long addr)
{
	return (void __iomem *)(addr + POLARIS_DENSE_IO_BASE);
}

__EXTERN_INLINE void __iomem *polaris_ioremap(unsigned long addr,
					      unsigned long size)
{
	return (void __iomem *)(addr + POLARIS_DENSE_MEM_BASE);
}

__EXTERN_INLINE int polaris_is_ioaddr(unsigned long addr)
{
	return addr >= POLARIS_SPARSE_MEM_BASE;
}

__EXTERN_INLINE int polaris_is_mmio(const volatile void __iomem *addr)
{
	return (unsigned long)addr < POLARIS_SPARSE_IO_BASE;
}

#undef __IO_PREFIX
#define __IO_PREFIX		polaris
#define polaris_trivial_rw_bw	1
#define polaris_trivial_rw_lq	1
#define polaris_trivial_io_bw	1
#define polaris_trivial_io_lq	1
#define polaris_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_POLARIS__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_T2__H__
#define __ALPHA_T2__H__

/* Fit everything into one 128MB HAE window. */
#define T2_ONE_HAE_WINDOW 1

#include <linux/types.h>
#include <linux/spinlock.h>
#include <asm/compiler.h>

/*
 * T2 is the internal name for the core logic chipset which provides
 * memory controller and PCI access for the SABLE-based systems.
 *
 * This file is based on:
 *
 * SABLE I/O Specification
 * Revision/Update Information: 1.3
 *
 * jestabro@amt.tay1.dec.com Initial Version.
 *
 */

#define T2_MEM_R1_MASK 0x07ffffff  /* Mem sparse region 1 mask is 27 bits */

/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
/* All LYNX machines, EV4 or EV5, use the GAMMA bias also */
#define _GAMMA_BIAS		0x8000000000UL

#if defined(CONFIG_ALPHA_GENERIC)
#define GAMMA_BIAS		alpha_mv.sys.t2.gamma_bias
#elif defined(CONFIG_ALPHA_GAMMA)
#define GAMMA_BIAS		_GAMMA_BIAS
#else
#define GAMMA_BIAS		0
#endif

/*
 * Memory spaces:
 */
#define T2_CONF		        (IDENT_ADDR + GAMMA_BIAS + 0x390000000UL)
#define T2_IO			(IDENT_ADDR + GAMMA_BIAS + 0x3a0000000UL)
#define T2_SPARSE_MEM		(IDENT_ADDR + GAMMA_BIAS + 0x200000000UL)
#define T2_DENSE_MEM	        (IDENT_ADDR + GAMMA_BIAS + 0x3c0000000UL)

#define T2_IOCSR		(IDENT_ADDR + GAMMA_BIAS + 0x38e000000UL)
#define T2_CERR1		(IDENT_ADDR + GAMMA_BIAS + 0x38e000020UL)
#define T2_CERR2		(IDENT_ADDR + GAMMA_BIAS + 0x38e000040UL)
#define T2_CERR3		(IDENT_ADDR + GAMMA_BIAS + 0x38e000060UL)
#define T2_PERR1		(IDENT_ADDR + GAMMA_BIAS + 0x38e000080UL)
#define T2_PERR2		(IDENT_ADDR + GAMMA_BIAS + 0x38e0000a0UL)
#define T2_PSCR			(IDENT_ADDR + GAMMA_BIAS + 0x38e0000c0UL)
#define T2_HAE_1		(IDENT_ADDR + GAMMA_BIAS + 0x38e0000e0UL)
#define T2_HAE_2		(IDENT_ADDR + GAMMA_BIAS + 0x38e000100UL)
#define T2_HBASE		(IDENT_ADDR + GAMMA_BIAS + 0x38e000120UL)
#define T2_WBASE1		(IDENT_ADDR + GAMMA_BIAS + 0x38e000140UL)
#define T2_WMASK1		(IDENT_ADDR + GAMMA_BIAS + 0x38e000160UL)
#define T2_TBASE1		(IDENT_ADDR + GAMMA_BIAS + 0x38e000180UL)
#define T2_WBASE2		(IDENT_ADDR + GAMMA_BIAS + 0x38e0001a0UL)
#define T2_WMASK2		(IDENT_ADDR + GAMMA_BIAS + 0x38e0001c0UL)
#define T2_TBASE2		(IDENT_ADDR + GAMMA_BIAS + 0x38e0001e0UL)
#define T2_TLBBR		(IDENT_ADDR + GAMMA_BIAS + 0x38e000200UL)
#define T2_IVR			(IDENT_ADDR + GAMMA_BIAS + 0x38e000220UL)
#define T2_HAE_3		(IDENT_ADDR + GAMMA_BIAS + 0x38e000240UL)
#define T2_HAE_4		(IDENT_ADDR + GAMMA_BIAS + 0x38e000260UL)

/* The CSRs below are T3/T4 only */
#define T2_WBASE3		(IDENT_ADDR + GAMMA_BIAS + 0x38e000280UL)
#define T2_WMASK3		(IDENT_ADDR + GAMMA_BIAS + 0x38e0002a0UL)
#define T2_TBASE3		(IDENT_ADDR + GAMMA_BIAS + 0x38e0002c0UL)

#define T2_TDR0			(IDENT_ADDR + GAMMA_BIAS + 0x38e000300UL)
#define T2_TDR1			(IDENT_ADDR + GAMMA_BIAS + 0x38e000320UL)
#define T2_TDR2			(IDENT_ADDR + GAMMA_BIAS + 0x38e000340UL)
#define T2_TDR3			(IDENT_ADDR + GAMMA_BIAS + 0x38e000360UL)
#define T2_TDR4			(IDENT_ADDR + GAMMA_BIAS + 0x38e000380UL)
#define T2_TDR5			(IDENT_ADDR + GAMMA_BIAS + 0x38e0003a0UL)
#define T2_TDR6			(IDENT_ADDR + GAMMA_BIAS + 0x38e0003c0UL)
#define T2_TDR7			(IDENT_ADDR + GAMMA_BIAS + 0x38e0003e0UL)

#define T2_WBASE4		(IDENT_ADDR + GAMMA_BIAS + 0x38e000400UL)
#define T2_WMASK4		(IDENT_ADDR + GAMMA_BIAS + 0x38e000420UL)
#define T2_TBASE4		(IDENT_ADDR + GAMMA_BIAS + 0x38e000440UL)

#define T2_AIR			(IDENT_ADDR + GAMMA_BIAS + 0x38e000460UL)
#define T2_VAR			(IDENT_ADDR + GAMMA_BIAS + 0x38e000480UL)
#define T2_DIR			(IDENT_ADDR + GAMMA_BIAS + 0x38e0004a0UL)
#define T2_ICE			(IDENT_ADDR + GAMMA_BIAS + 0x38e0004c0UL)

#ifndef T2_ONE_HAE_WINDOW
#define T2_HAE_ADDRESS		T2_HAE_1
#endif

/*  T2 CSRs are in the non-cachable primary IO space from 3.8000.0000 to
 3.8fff.ffff
 *
 *  +--------------+ 3 8000 0000
 *  | CPU 0 CSRs   |
 *  +--------------+ 3 8100 0000
 *  | CPU 1 CSRs   |
 *  +--------------+ 3 8200 0000
 *  | CPU 2 CSRs   |
 *  +--------------+ 3 8300 0000
 *  | CPU 3 CSRs   |
 *  +--------------+ 3 8400 0000
 *  | CPU Reserved |
 *  +--------------+ 3 8700 0000
 *  | Mem Reserved |
 *  +--------------+ 3 8800 0000
 *  | Mem 0 CSRs   |
 *  +--------------+ 3 8900 0000
 *  | Mem 1 CSRs   |
 *  +--------------+ 3 8a00 0000
 *  | Mem 2 CSRs   |
 *  +--------------+ 3 8b00 0000
 *  | Mem 3 CSRs   |
 *  +--------------+ 3 8c00 0000
 *  | Mem Reserved |
 *  +--------------+ 3 8e00 0000
 *  | PCI Bridge   |
 *  +--------------+ 3 8f00 0000
 *  | Expansion IO |
 *  +--------------+ 3 9000 0000
 *
 *
 */
#define T2_CPU0_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x380000000L)
#define T2_CPU1_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x381000000L)
#define T2_CPU2_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x382000000L)
#define T2_CPU3_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x383000000L)

#define T2_CPUn_BASE(n)		(T2_CPU0_BASE + (((n)&3) * 0x001000000L))

#define T2_MEM0_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x388000000L)
#define T2_MEM1_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x389000000L)
#define T2_MEM2_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x38a000000L)
#define T2_MEM3_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x38b000000L)

/*
 * Sable CPU Module CSRS
 *
 * These are CSRs for hardware other than the CPU chip on the CPU module.
 * The CPU module has Backup Cache control logic, Cbus control logic, and
 * interrupt control logic on it.  There is a duplicate tag store to speed
 * up maintaining cache coherency.
 */

struct sable_cpu_csr {
  unsigned long bcc;     long fill_00[3]; /* Backup Cache Control */
  unsigned long bcce;    long fill_01[3]; /* Backup Cache Correctable Error */
  unsigned long bccea;   long fill_02[3]; /* B-Cache Corr Err Address Latch */
  unsigned long bcue;    long fill_03[3]; /* B-Cache Uncorrectable Error */
  unsigned long bcuea;   long fill_04[3]; /* B-Cache Uncorr Err Addr Latch */
  unsigned long dter;    long fill_05[3]; /* Duplicate Tag Error */
  unsigned long cbctl;   long fill_06[3]; /* CBus Control */
  unsigned long cbe;     long fill_07[3]; /* CBus Error */
  unsigned long cbeal;   long fill_08[3]; /* CBus Error Addr Latch low */
  unsigned long cbeah;   long fill_09[3]; /* CBus Error Addr Latch high */
  unsigned long pmbx;    long fill_10[3]; /* Processor Mailbox */
  unsigned long ipir;    long fill_11[3]; /* Inter-Processor Int Request */
  unsigned long sic;     long fill_12[3]; /* System Interrupt Clear */
  unsigned long adlk;    long fill_13[3]; /* Address Lock (LDxL/STxC) */
  unsigned long madrl;   long fill_14[3]; /* CBus Miss Address */
  unsigned long rev;     long fill_15[3]; /* CMIC Revision */
};

/*
 * Data structure for handling T2 machine checks:
 */
struct el_t2_frame_header {
	unsigned int	elcf_fid;	/* Frame ID (from above) */
	unsigned int	elcf_size;	/* Size of frame in bytes */
};

struct el_t2_procdata_mcheck {
	unsigned long	elfmc_paltemp[32];	/* PAL TEMP REGS. */
	/* EV4-specific fields */
	unsigned long	elfmc_exc_addr;	/* Addr of excepting insn. */
	unsigned long	elfmc_exc_sum;	/* Summary of arith traps. */
	unsigned long	elfmc_exc_mask;	/* Exception mask (from exc_sum). */
	unsigned long	elfmc_iccsr;	/* IBox hardware enables. */
	unsigned long	elfmc_pal_base;	/* Base address for PALcode. */
	unsigned long	elfmc_hier;	/* Hardware Interrupt Enable. */
	unsigned long	elfmc_hirr;	/* Hardware Interrupt Request. */
	unsigned long	elfmc_mm_csr;	/* D-stream fault info. */
	unsigned long	elfmc_dc_stat;	/* D-cache status (ECC/Parity Err). */
	unsigned long	elfmc_dc_addr;	/* EV3 Phys Addr for ECC/DPERR. */
	unsigned long	elfmc_abox_ctl;	/* ABox Control Register. */
	unsigned long	elfmc_biu_stat;	/* BIU Status. */
	unsigned long	elfmc_biu_addr;	/* BUI Address. */
	unsigned long	elfmc_biu_ctl;	/* BIU Control. */
	unsigned long	elfmc_fill_syndrome; /* For correcting ECC errors. */
	unsigned long	elfmc_fill_addr;/* Cache block which was being read. */
	unsigned long	elfmc_va;	/* Effective VA of fault or miss. */
	unsigned long	elfmc_bc_tag;	/* Backup Cache Tag Probe Results. */
};

/*
 * Sable processor specific Machine Check Data segment.
 */

struct el_t2_logout_header {
	unsigned int	elfl_size;	/* size in bytes of logout area. */
	unsigned int	elfl_sbz1:31;	/* Should be zero. */
	unsigned int	elfl_retry:1;	/* Retry flag. */
	unsigned int	elfl_procoffset; /* Processor-specific offset. */
	unsigned int	elfl_sysoffset;	 /* Offset of system-specific. */
	unsigned int	elfl_error_type;	/* PAL error type code. */
	unsigned int	elfl_frame_rev;		/* PAL Frame revision. */
};
struct el_t2_sysdata_mcheck {
	unsigned long    elcmc_bcc;	      /* CSR 0 */
	unsigned long    elcmc_bcce;	      /* CSR 1 */
	unsigned long    elcmc_bccea;      /* CSR 2 */
	unsigned long    elcmc_bcue;	      /* CSR 3 */
	unsigned long    elcmc_bcuea;      /* CSR 4 */
	unsigned long    elcmc_dter;	      /* CSR 5 */
	unsigned long    elcmc_cbctl;      /* CSR 6 */
	unsigned long    elcmc_cbe;	      /* CSR 7 */
	unsigned long    elcmc_cbeal;      /* CSR 8 */
	unsigned long    elcmc_cbeah;      /* CSR 9 */
	unsigned long    elcmc_pmbx;	      /* CSR 10 */
	unsigned long    elcmc_ipir;	      /* CSR 11 */
	unsigned long    elcmc_sic;	      /* CSR 12 */
	unsigned long    elcmc_adlk;	      /* CSR 13 */
	unsigned long    elcmc_madrl;      /* CSR 14 */
	unsigned long    elcmc_crrev4;     /* CSR 15 */
};

/*
 * Sable memory error frame - sable pfms section 3.42
 */
struct el_t2_data_memory {
	struct	el_t2_frame_header elcm_hdr;	/* ID$MEM-FERR = 0x08 */
	unsigned int  elcm_module;	/* Module id. */
	unsigned int  elcm_res04;	/* Reserved. */
	unsigned long elcm_merr;	/* CSR0: Error Reg 1. */
	unsigned long elcm_mcmd1;	/* CSR1: Command Trap 1. */
	unsigned long elcm_mcmd2;	/* CSR2: Command Trap 2. */
	unsigned long elcm_mconf;	/* CSR3: Configuration. */
	unsigned long elcm_medc1;	/* CSR4: EDC Status 1. */
	unsigned long elcm_medc2;	/* CSR5: EDC Status 2. */
	unsigned long elcm_medcc;	/* CSR6: EDC Control. */
	unsigned long elcm_msctl;	/* CSR7: Stream Buffer Control. */
	unsigned long elcm_mref;	/* CSR8: Refresh Control. */
	unsigned long elcm_filter;	/* CSR9: CRD Filter Control. */
};

/*
 * Sable other CPU error frame - sable pfms section 3.43
 */
struct el_t2_data_other_cpu {
	short	      elco_cpuid;	/* CPU ID */
	short	      elco_res02[3];
	unsigned long elco_bcc;	/* CSR 0 */
	unsigned long elco_bcce;	/* CSR 1 */
	unsigned long elco_bccea;	/* CSR 2 */
	unsigned long elco_bcue;	/* CSR 3 */
	unsigned long elco_bcuea;	/* CSR 4 */
	unsigned long elco_dter;	/* CSR 5 */
	unsigned long elco_cbctl;	/* CSR 6 */
	unsigned long elco_cbe;	/* CSR 7 */
	unsigned long elco_cbeal;	/* CSR 8 */
	unsigned long elco_cbeah;	/* CSR 9 */
	unsigned long elco_pmbx;	/* CSR 10 */
	unsigned long elco_ipir;	/* CSR 11 */
	unsigned long elco_sic;	/* CSR 12 */
	unsigned long elco_adlk;	/* CSR 13 */
	unsigned long elco_madrl;	/* CSR 14 */
	unsigned long elco_crrev4;	/* CSR 15 */
};

/*
 * Sable other CPU error frame - sable pfms section 3.44
 */
struct el_t2_data_t2{
	struct el_t2_frame_header elct_hdr;	/* ID$T2-FRAME */
	unsigned long elct_iocsr;	/* IO Control and Status Register */
	unsigned long elct_cerr1;	/* Cbus Error Register 1 */
	unsigned long elct_cerr2;	/* Cbus Error Register 2 */
	unsigned long elct_cerr3;	/* Cbus Error Register 3 */
	unsigned long elct_perr1;	/* PCI Error Register 1 */
	unsigned long elct_perr2;	/* PCI Error Register 2 */
	unsigned long elct_hae0_1;	/* High Address Extension Register 1 */
	unsigned long elct_hae0_2;	/* High Address Extension Register 2 */
	unsigned long elct_hbase;	/* High Base Register */
	unsigned long elct_wbase1;	/* Window Base Register 1 */
	unsigned long elct_wmask1;	/* Window Mask Register 1 */
	unsigned long elct_tbase1;	/* Translated Base Register 1 */
	unsigned long elct_wbase2;	/* Window Base Register 2 */
	unsigned long elct_wmask2;	/* Window Mask Register 2 */
	unsigned long elct_tbase2;	/* Translated Base Register 2 */
	unsigned long elct_tdr0;	/* TLB Data Register 0 */
	unsigned long elct_tdr1;	/* TLB Data Register 1 */
	unsigned long elct_tdr2;	/* TLB Data Register 2 */
	unsigned long elct_tdr3;	/* TLB Data Register 3 */
	unsigned long elct_tdr4;	/* TLB Data Register 4 */
	unsigned long elct_tdr5;	/* TLB Data Register 5 */
	unsigned long elct_tdr6;	/* TLB Data Register 6 */
	unsigned long elct_tdr7;	/* TLB Data Register 7 */
};

/*
 * Sable error log data structure - sable pfms section 3.40
 */
struct el_t2_data_corrected {
	unsigned long elcpb_biu_stat;
	unsigned long elcpb_biu_addr;
	unsigned long elcpb_biu_ctl;
	unsigned long elcpb_fill_syndrome;
	unsigned long elcpb_fill_addr;
	unsigned long elcpb_bc_tag;
};

/*
 * Sable error log data structure
 * Note there are 4 memory slots on sable (see t2.h)
 */
struct el_t2_frame_mcheck {
	struct el_t2_frame_header elfmc_header;	/* ID$P-FRAME_MCHECK */
	struct el_t2_logout_header elfmc_hdr;
	struct el_t2_procdata_mcheck elfmc_procdata;
	struct el_t2_sysdata_mcheck elfmc_sysdata;
	struct el_t2_data_t2 elfmc_t2data;
	struct el_t2_data_memory elfmc_memdata[4];
	struct el_t2_frame_header elfmc_footer;	/* empty */
};

/*
 * Sable error log data structures on memory errors
 */
struct el_t2_frame_corrected {
	struct el_t2_frame_header elfcc_header;	/* ID$P-BC-COR */
	struct el_t2_logout_header elfcc_hdr;
	struct el_t2_data_corrected elfcc_procdata;
/*	struct el_t2_data_t2 elfcc_t2data;		*/
/*	struct el_t2_data_memory elfcc_memdata[4];	*/
	struct el_t2_frame_header elfcc_footer;	/* empty */
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * T2 (the core logic PCI/memory support chipset for the SABLE
 * series of processors uses a sparse address mapping scheme to
 * get at PCI memory and I/O.
 */

#define vip	volatile int *
#define vuip	volatile unsigned int *
#define vulp	volatile unsigned long *

extern inline u8 t2_inb(unsigned long addr)
{
	long result = *(vip) ((addr << 5) + T2_IO + 0x00);
	return __kernel_extbl(result, addr & 3);
}

extern inline void t2_outb(u8 b, unsigned long addr)
{
	unsigned long w;

	w = __kernel_insbl(b, addr & 3);
	*(vuip) ((addr << 5) + T2_IO + 0x00) = w;
	mb();
}

extern inline u16 t2_inw(unsigned long addr)
{
	long result = *(vip) ((addr << 5) + T2_IO + 0x08);
	return __kernel_extwl(result, addr & 3);
}

extern inline void t2_outw(u16 b, unsigned long addr)
{
	unsigned long w;

	w = __kernel_inswl(b, addr & 3);
	*(vuip) ((addr << 5) + T2_IO + 0x08) = w;
	mb();
}

extern inline u32 t2_inl(unsigned long addr)
{
	return *(vuip) ((addr << 5) + T2_IO + 0x18);
}

extern inline void t2_outl(u32 b, unsigned long addr)
{
	*(vuip) ((addr << 5) + T2_IO + 0x18) = b;
	mb();
}

extern inline u64 t2_inq(unsigned long addr)
{
	return *(vulp) ((addr << 5) + T2_IO + 0x18);
}

extern inline void t2_outq(u64 b, unsigned long addr)
{
	*(vulp) ((addr << 5) + T2_IO + 0x18) = b;
	mb();
}

/*
 * Memory functions.
 *
 * For reading and writing 8 and 16 bit quantities we need to
 * go through one of the three sparse address mapping regions
 * and use the HAE_MEM CSR to provide some bits of the address.
 * The following few routines use only sparse address region 1
 * which gives 1Gbyte of accessible space which relates exactly
 * to the amount of PCI memory mapping *into* system address space.
 * See p 6-17 of the specification but it looks something like this:
 *
 * 21164 Address:
 *
 *          3         2         1
 * 9876543210987654321098765432109876543210
 * 1ZZZZ0.PCI.QW.Address............BBLL
 *
 * ZZ = SBZ
 * BB = Byte offset
 * LL = Transfer length
 *
 * PCI Address:
 *
 * 3         2         1
 * 10987654321098765432109876543210
 * HHH....PCI.QW.Address........ 00
 *
 * HHH = 31:29 HAE_MEM CSR
 *
 */

#ifdef T2_ONE_HAE_WINDOW
#define t2_set_hae
#else
#define t2_set_hae { \
	unsigned long msb = addr >> 27; \
	addr &= T2_MEM_R1_MASK; \
	set_hae(msb); \
}
#endif

/*
 * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
 *       they may be called directly, rather than through the
 *       ioreadNN/iowriteNN routines.
 */

__EXTERN_INLINE u8 t2_readb(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long result;

	t2_set_hae;

	result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00);
	return __kernel_extbl(result, addr & 3);
}

__EXTERN_INLINE u16 t2_readw(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long result;

	t2_set_hae;

	result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
	return __kernel_extwl(result, addr & 3);
}

/*
 * On SABLE with T2, we must use SPARSE memory even for 32-bit access,
 * because we cannot access all of DENSE without changing its HAE.
 */
__EXTERN_INLINE u32 t2_readl(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long result;

	t2_set_hae;

	result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
	return result & 0xffffffffUL;
}

__EXTERN_INLINE u64 t2_readq(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long r0, r1, work;

	t2_set_hae;

	work = (addr << 5) + T2_SPARSE_MEM + 0x18;
	r0 = *(vuip)(work);
	r1 = *(vuip)(work + (4 << 5));
	return r1 << 32 | r0;
}

__EXTERN_INLINE void t2_writeb(u8 b, volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long w;

	t2_set_hae;

	w = __kernel_insbl(b, addr & 3);
	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = w;
}

__EXTERN_INLINE void t2_writew(u16 b, volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long w;

	t2_set_hae;

	w = __kernel_inswl(b, addr & 3);
	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = w;
}

/*
 * On SABLE with T2, we must use SPARSE memory even for 32-bit access,
 * because we cannot access all of DENSE without changing its HAE.
 */
__EXTERN_INLINE void t2_writel(u32 b, volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;

	t2_set_hae;

	*(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
}

__EXTERN_INLINE void t2_writeq(u64 b, volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr - T2_DENSE_MEM;
	unsigned long work;

	t2_set_hae;

	work = (addr << 5) + T2_SPARSE_MEM + 0x18;
	*(vuip)work = b;
	*(vuip)(work + (4 << 5)) = b >> 32;
}

__EXTERN_INLINE void __iomem *t2_ioportmap(unsigned long addr)
{
	return (void __iomem *)(addr + T2_IO);
}

__EXTERN_INLINE void __iomem *t2_ioremap(unsigned long addr,
					 unsigned long size)
{
	return (void __iomem *)(addr + T2_DENSE_MEM);
}

__EXTERN_INLINE int t2_is_ioaddr(unsigned long addr)
{
	return (long)addr >= 0;
}

__EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
{
	return (unsigned long)addr >= T2_DENSE_MEM;
}

/* New-style ioread interface.  The mmio routines are so ugly for T2 that
   it doesn't make sense to merge the pio and mmio routines.  */

#define IOPORT(OS, NS)							\
__EXTERN_INLINE u##NS t2_ioread##NS(const void __iomem *xaddr)		\
{									\
	if (t2_is_mmio(xaddr))						\
		return t2_read##OS(xaddr);				\
	else								\
		return t2_in##OS((unsigned long)xaddr - T2_IO);		\
}									\
__EXTERN_INLINE void t2_iowrite##NS(u##NS b, void __iomem *xaddr)	\
{									\
	if (t2_is_mmio(xaddr))						\
		t2_write##OS(b, xaddr);					\
	else								\
		t2_out##OS(b, (unsigned long)xaddr - T2_IO);		\
}

IOPORT(b, 8)
IOPORT(w, 16)
IOPORT(l, 32)
IOPORT(q, 64)

#undef IOPORT

#undef vip
#undef vuip
#undef vulp

#undef __IO_PREFIX
#define __IO_PREFIX		t2
#define t2_trivial_rw_bw	0
#define t2_trivial_rw_lq	0
#define t2_trivial_io_bw	0
#define t2_trivial_io_lq	0
#define t2_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_T2__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_TITAN__H__
#define __ALPHA_TITAN__H__

#include <linux/types.h>
#include <asm/compiler.h>

/*
 * TITAN is the internal names for a core logic chipset which provides
 * memory controller and PCI/AGP access for 21264 based systems.
 *
 * This file is based on:
 *
 * Titan Chipset Engineering Specification
 * Revision 0.12
 * 13 July 1999
 *
 */

/* XXX: Do we need to conditionalize on this?  */
#ifdef USE_48_BIT_KSEG
#define TI_BIAS 0x80000000000UL
#else
#define TI_BIAS 0x10000000000UL
#endif

/*
 * CChip, DChip, and PChip registers
 */

typedef struct {
	volatile unsigned long csr __attribute__((aligned(64)));
} titan_64;

typedef struct {
	titan_64	csc;
	titan_64	mtr;
	titan_64	misc;
	titan_64	mpd;
	titan_64	aar0;
	titan_64	aar1;
	titan_64	aar2;
	titan_64	aar3;
	titan_64	dim0;
	titan_64	dim1;
	titan_64	dir0;
	titan_64	dir1;
	titan_64	drir;
	titan_64	prben;
	titan_64	iic0;
	titan_64	iic1;
	titan_64	mpr0;
	titan_64	mpr1;
	titan_64	mpr2;
	titan_64	mpr3;
	titan_64	rsvd[2];
	titan_64	ttr;
	titan_64	tdr;
	titan_64	dim2;
	titan_64	dim3;
	titan_64	dir2;
	titan_64	dir3;
	titan_64	iic2;
	titan_64	iic3;
	titan_64	pwr;
	titan_64	reserved[17];
	titan_64	cmonctla;
	titan_64	cmonctlb;
	titan_64	cmoncnt01;
	titan_64	cmoncnt23;
	titan_64	cpen;
} titan_cchip;

typedef struct {
	titan_64	dsc;
	titan_64	str;
	titan_64	drev;
	titan_64	dsc2;
} titan_dchip;

typedef struct {
	titan_64	wsba[4];
	titan_64	wsm[4];
	titan_64	tba[4];
	titan_64	pctl;
	titan_64	plat;
	titan_64	reserved0[2];
	union {
		struct {
			titan_64	serror;
			titan_64	serren;
			titan_64	serrset;
			titan_64	reserved0;
			titan_64	gperror;
			titan_64	gperren;
			titan_64	gperrset;
			titan_64	reserved1;
			titan_64	gtlbiv;
			titan_64	gtlbia;
			titan_64	reserved2[2];
			titan_64	sctl;
			titan_64	reserved3[3];
		} g;
		struct {
			titan_64	agperror;
			titan_64	agperren;
			titan_64	agperrset;
			titan_64	agplastwr;
			titan_64	aperror;
			titan_64	aperren;
			titan_64	aperrset;
			titan_64	reserved0;
			titan_64	atlbiv;
			titan_64	atlbia;
			titan_64	reserved1[6];
		} a;
	} port_specific;
	titan_64	sprst;
	titan_64	reserved1[31];
} titan_pachip_port;

typedef struct {
	titan_pachip_port	g_port;
	titan_pachip_port	a_port;
} titan_pachip;

#define TITAN_cchip	((titan_cchip  *)(IDENT_ADDR+TI_BIAS+0x1A0000000UL))
#define TITAN_dchip    	((titan_dchip  *)(IDENT_ADDR+TI_BIAS+0x1B0000800UL))
#define TITAN_pachip0 	((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x180000000UL))
#define TITAN_pachip1 	((titan_pachip *)(IDENT_ADDR+TI_BIAS+0x380000000UL))
extern unsigned TITAN_agp;
extern int TITAN_bootcpu;

/*
 * TITAN PA-chip Window Space Base Address register.
 * (WSBA[0-2])
 */
#define wsba_m_ena 0x1
#define wsba_m_sg 0x2
#define wsba_m_addr 0xFFF00000
#define wmask_k_sz1gb 0x3FF00000
union TPAchipWSBA {
	struct  {
		unsigned wsba_v_ena : 1;
		unsigned wsba_v_sg : 1;
		unsigned wsba_v_rsvd1 : 18;
		unsigned wsba_v_addr : 12;
		unsigned wsba_v_rsvd2 : 32;
        } wsba_r_bits;
	int wsba_q_whole [2];
};

/*
 * TITAN PA-chip Control Register
 * This definition covers both the G-Port GPCTL and the A-PORT APCTL.
 * Bits <51:0> are the same in both cases. APCTL<63:52> are only
 * applicable to AGP.
 */
#define pctl_m_fbtb 			0x00000001
#define pctl_m_thdis 			0x00000002
#define pctl_m_chaindis 		0x00000004
#define pctl_m_tgtlat 			0x00000018
#define pctl_m_hole  	  		0x00000020
#define pctl_m_mwin 	  		0x00000040
#define pctl_m_arbena 	  		0x00000080
#define pctl_m_prigrp 	  		0x0000FF00
#define pctl_m_ppri 	  		0x00010000
#define pctl_m_pcispd66  		0x00020000
#define pctl_m_cngstlt	  		0x003C0000
#define pctl_m_ptpdesten 		0x3FC00000
#define pctl_m_dpcen			0x40000000
#define pctl_m_apcen		0x0000000080000000UL
#define pctl_m_dcrtv		0x0000000300000000UL
#define pctl_m_en_stepping	0x0000000400000000UL
#define apctl_m_rsvd1		0x000FFFF800000000UL
#define apctl_m_agp_rate	0x0030000000000000UL
#define apctl_m_agp_sba_en	0x0040000000000000UL
#define apctl_m_agp_en		0x0080000000000000UL
#define apctl_m_rsvd2		0x0100000000000000UL
#define apctl_m_agp_present	0x0200000000000000UL
#define apctl_agp_hp_rd		0x1C00000000000000UL
#define apctl_agp_lp_rd		0xE000000000000000UL
#define gpctl_m_rsvd		0xFFFFFFF800000000UL
union TPAchipPCTL {
	struct {
		unsigned pctl_v_fbtb : 1;		/* A/G [0]     */
		unsigned pctl_v_thdis : 1;		/* A/G [1]     */
		unsigned pctl_v_chaindis : 1;		/* A/G [2]     */
		unsigned pctl_v_tgtlat : 2;		/* A/G [4:3]   */
		unsigned pctl_v_hole : 1;		/* A/G [5]     */
		unsigned pctl_v_mwin : 1;		/* A/G [6]     */
		unsigned pctl_v_arbena : 1;		/* A/G [7]     */
		unsigned pctl_v_prigrp : 8;		/* A/G [15:8]  */
		unsigned pctl_v_ppri : 1;		/* A/G [16]    */
		unsigned pctl_v_pcispd66 : 1;		/* A/G [17]    */
		unsigned pctl_v_cngstlt : 4;		/* A/G [21:18] */
		unsigned pctl_v_ptpdesten : 8;		/* A/G [29:22] */
		unsigned pctl_v_dpcen : 1;		/* A/G [30]    */
		unsigned pctl_v_apcen : 1;		/* A/G [31]    */
		unsigned pctl_v_dcrtv : 2;		/* A/G [33:32] */
		unsigned pctl_v_en_stepping :1;		/* A/G [34]    */
		unsigned apctl_v_rsvd1 : 17;		/* A   [51:35] */
		unsigned apctl_v_agp_rate : 2;		/* A   [53:52] */
		unsigned apctl_v_agp_sba_en : 1;	/* A   [54]    */
		unsigned apctl_v_agp_en : 1;		/* A   [55]    */
		unsigned apctl_v_rsvd2 : 1;		/* A   [56]    */
		unsigned apctl_v_agp_present : 1;	/* A   [57]    */
		unsigned apctl_v_agp_hp_rd : 3;		/* A   [60:58] */
		unsigned apctl_v_agp_lp_rd : 3;		/* A   [63:61] */
	} pctl_r_bits;
	unsigned int pctl_l_whole [2];
	unsigned long pctl_q_whole;
};

/*
 * SERROR / SERREN / SERRSET
 */
union TPAchipSERR {
	struct {
		unsigned serr_v_lost_uecc : 1;		/* [0]		*/
		unsigned serr_v_uecc : 1;		/* [1]  	*/
		unsigned serr_v_cre : 1;		/* [2]		*/
		unsigned serr_v_nxio : 1;		/* [3]		*/
		unsigned serr_v_lost_cre : 1;		/* [4]		*/
		unsigned serr_v_rsvd0 : 10;		/* [14:5]	*/
		unsigned serr_v_addr : 32;		/* [46:15]	*/
		unsigned serr_v_rsvd1 : 5;		/* [51:47]	*/
		unsigned serr_v_source : 2;		/* [53:52]	*/
		unsigned serr_v_cmd : 2;		/* [55:54]	*/
		unsigned serr_v_syn : 8;		/* [63:56]	*/
	} serr_r_bits;
	unsigned int serr_l_whole[2];
	unsigned long serr_q_whole;
};

/*
 * GPERROR / APERROR / GPERREN / APERREN / GPERRSET / APERRSET
 */
union TPAchipPERR {
	struct {
		unsigned long perr_v_lost : 1;	     	/* [0]		*/
		unsigned long perr_v_serr : 1;		/* [1]		*/
		unsigned long perr_v_perr : 1;		/* [2]		*/
		unsigned long perr_v_dcrto : 1;		/* [3]		*/
		unsigned long perr_v_sge : 1;		/* [4]		*/
		unsigned long perr_v_ape : 1;		/* [5]		*/
		unsigned long perr_v_ta : 1;		/* [6]		*/
		unsigned long perr_v_dpe : 1;		/* [7]		*/
		unsigned long perr_v_nds : 1;		/* [8]		*/
		unsigned long perr_v_iptpr : 1;		/* [9]		*/
		unsigned long perr_v_iptpw : 1;		/* [10] 	*/
		unsigned long perr_v_rsvd0 : 3;		/* [13:11]	*/
		unsigned long perr_v_addr : 33;		/* [46:14]	*/
		unsigned long perr_v_dac : 1;		/* [47]		*/
		unsigned long perr_v_mwin : 1;		/* [48]		*/
		unsigned long perr_v_rsvd1 : 3;		/* [51:49]	*/
		unsigned long perr_v_cmd : 4;		/* [55:52]	*/
		unsigned long perr_v_rsvd2 : 8;		/* [63:56]	*/
	} perr_r_bits;
	unsigned int perr_l_whole[2];
	unsigned long perr_q_whole;
};

/*
 * AGPERROR / AGPERREN / AGPERRSET
 */
union TPAchipAGPERR {
	struct {
		unsigned agperr_v_lost : 1;		/* [0]		*/
		unsigned agperr_v_lpqfull : 1;		/* [1]		*/
		unsigned apgerr_v_hpqfull : 1;		/* [2]		*/
		unsigned agperr_v_rescmd : 1;		/* [3]		*/
		unsigned agperr_v_ipte : 1;		/* [4]		*/
		unsigned agperr_v_ptp :	1;      	/* [5]		*/
		unsigned agperr_v_nowindow : 1;		/* [6]		*/
		unsigned agperr_v_rsvd0 : 8;		/* [14:7]	*/
		unsigned agperr_v_addr : 32;		/* [46:15]	*/
		unsigned agperr_v_rsvd1 : 1;		/* [47]		*/
		unsigned agperr_v_dac : 1;		/* [48]		*/
		unsigned agperr_v_mwin : 1;		/* [49]		*/
		unsigned agperr_v_cmd : 3;		/* [52:50]	*/
		unsigned agperr_v_length : 6;		/* [58:53]	*/
		unsigned agperr_v_fence : 1;		/* [59]		*/
		unsigned agperr_v_rsvd2 : 4;		/* [63:60]	*/
	} agperr_r_bits;
	unsigned int agperr_l_whole[2];
	unsigned long agperr_q_whole;
};
/*
 * Memory spaces:
 * Hose numbers are assigned as follows:
 *		0 - pachip 0 / G Port
 *		1 - pachip 1 / G Port
 * 		2 - pachip 0 / A Port
 *      	3 - pachip 1 / A Port
 */
#define TITAN_HOSE_SHIFT       (33)
#define TITAN_HOSE(h)		(((unsigned long)(h)) << TITAN_HOSE_SHIFT)
#define TITAN_BASE		(IDENT_ADDR + TI_BIAS)
#define TITAN_MEM(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x000000000UL)
#define _TITAN_IACK_SC(h)    	(TITAN_BASE+TITAN_HOSE(h)+0x1F8000000UL)
#define TITAN_IO(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x1FC000000UL)
#define TITAN_CONF(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x1FE000000UL)

#define TITAN_HOSE_MASK		TITAN_HOSE(3)
#define TITAN_IACK_SC	     	_TITAN_IACK_SC(0) /* hack! */

/*
 * The canonical non-remaped I/O and MEM addresses have these values
 * subtracted out.  This is arranged so that folks manipulating ISA
 * devices can use their familiar numbers and have them map to bus 0.
 */

#define TITAN_IO_BIAS		TITAN_IO(0)
#define TITAN_MEM_BIAS		TITAN_MEM(0)

/* The IO address space is larger than 0xffff */
#define TITAN_IO_SPACE		(TITAN_CONF(0) - TITAN_IO(0))

/* TIG Space */
#define TITAN_TIG_SPACE		(TITAN_BASE + 0x100000000UL)

/* Offset between ram physical addresses and pci64 DAC bus addresses.  */
/* ??? Just a guess.  Ought to confirm it hasn't been moved.  */
#define TITAN_DAC_OFFSET	(1UL << 40)

/*
 * Data structure for handling TITAN machine checks:
 */
#define SCB_Q_SYSERR	0x620
#define SCB_Q_PROCERR	0x630
#define SCB_Q_SYSMCHK	0x660
#define SCB_Q_PROCMCHK	0x670
#define SCB_Q_SYSEVENT	0x680	/* environmental / system management */
struct el_TITAN_sysdata_mcheck {
	u64 summary;	/* 0x00 */
	u64 c_dirx;	/* 0x08 */
	u64 c_misc;	/* 0x10 */
	u64 p0_serror;	/* 0x18 */
	u64 p0_gperror; /* 0x20 */
	u64 p0_aperror; /* 0x28 */
	u64 p0_agperror;/* 0x30 */
	u64 p1_serror;	/* 0x38 */
	u64 p1_gperror; /* 0x40 */
	u64 p1_aperror; /* 0x48 */
	u64 p1_agperror;/* 0x50 */
};

/*
 * System area for a privateer 680 environmental/system management mcheck
 */
struct el_PRIVATEER_envdata_mcheck {
	u64 summary;	/* 0x00 */
	u64 c_dirx;	/* 0x08 */
	u64 smir;	/* 0x10 */
	u64 cpuir;	/* 0x18 */
	u64 psir;	/* 0x20 */
	u64 fault;	/* 0x28 */
	u64 sys_doors;	/* 0x30 */
	u64 temp_warn;	/* 0x38 */
	u64 fan_ctrl;	/* 0x40 */
	u64 code;	/* 0x48 */
	u64 reserved;	/* 0x50 */
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * TITAN, a 21??? PCI/memory support chipset for the EV6 (21264)
 * can only use linear accesses to get at PCI/AGP memory and I/O spaces.
 */

/*
 * Memory functions.  all accesses are done through linear space.
 */
extern void __iomem *titan_ioportmap(unsigned long addr);
extern void __iomem *titan_ioremap(unsigned long addr, unsigned long size);
extern void titan_iounmap(volatile void __iomem *addr);

__EXTERN_INLINE int titan_is_ioaddr(unsigned long addr)
{
	return addr >= TITAN_BASE;
}

extern int titan_is_mmio(const volatile void __iomem *addr);

#undef __IO_PREFIX
#define __IO_PREFIX		titan
#define titan_trivial_rw_bw	1
#define titan_trivial_rw_lq	1
#define titan_trivial_io_bw	1
#define titan_trivial_io_lq	1
#define titan_trivial_iounmap	0
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_TITAN__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_TSUNAMI__H__
#define __ALPHA_TSUNAMI__H__

#include <linux/types.h>
#include <asm/compiler.h>

/*
 * TSUNAMI/TYPHOON are the internal names for the core logic chipset which
 * provides memory controller and PCI access for the 21264 based systems.
 *
 * This file is based on:
 *
 * Tsunami System Programmers Manual
 * Preliminary, Chapters 2-5
 *
 */

/* XXX: Do we need to conditionalize on this?  */
#ifdef USE_48_BIT_KSEG
#define TS_BIAS 0x80000000000UL
#else
#define TS_BIAS 0x10000000000UL
#endif

/*
 * CChip, DChip, and PChip registers
 */

typedef struct {
	volatile unsigned long csr __attribute__((aligned(64)));
} tsunami_64;

typedef struct {
	tsunami_64	csc;
	tsunami_64	mtr;
	tsunami_64	misc;
	tsunami_64	mpd;
	tsunami_64	aar0;
	tsunami_64	aar1;
	tsunami_64	aar2;
	tsunami_64	aar3;
	tsunami_64	dim0;
	tsunami_64	dim1;
	tsunami_64	dir0;
	tsunami_64	dir1;
	tsunami_64	drir;
	tsunami_64	prben;
	tsunami_64	iic;	/* a.k.a. iic0 */
	tsunami_64	wdr;	/* a.k.a. iic1 */
	tsunami_64	mpr0;
	tsunami_64	mpr1;
	tsunami_64	mpr2;
	tsunami_64	mpr3;
	tsunami_64	mctl;
	tsunami_64	__pad1;
	tsunami_64	ttr;
	tsunami_64	tdr;
	tsunami_64	dim2;
	tsunami_64	dim3;
	tsunami_64	dir2;
	tsunami_64	dir3;
	tsunami_64	iic2;
	tsunami_64	iic3;
} tsunami_cchip;

typedef struct {
	tsunami_64	dsc;
	tsunami_64	str;
	tsunami_64	drev;
} tsunami_dchip;

typedef struct {
	tsunami_64	wsba[4];
	tsunami_64	wsm[4];
	tsunami_64	tba[4];
	tsunami_64	pctl;
	tsunami_64	plat;
	tsunami_64	reserved;
	tsunami_64	perror;
	tsunami_64	perrmask;
	tsunami_64	perrset;
	tsunami_64	tlbiv;
	tsunami_64	tlbia;
	tsunami_64	pmonctl;
	tsunami_64	pmoncnt;
} tsunami_pchip;

#define TSUNAMI_cchip  ((tsunami_cchip *)(IDENT_ADDR+TS_BIAS+0x1A0000000UL))
#define TSUNAMI_dchip  ((tsunami_dchip *)(IDENT_ADDR+TS_BIAS+0x1B0000800UL))
#define TSUNAMI_pchip0 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x180000000UL))
#define TSUNAMI_pchip1 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x380000000UL))
extern int TSUNAMI_bootcpu;

/*
 * TSUNAMI Pchip Error register.
 */

#define perror_m_lost 0x1
#define perror_m_serr 0x2
#define perror_m_perr 0x4
#define perror_m_dcrto 0x8
#define perror_m_sge 0x10
#define perror_m_ape 0x20
#define perror_m_ta 0x40
#define perror_m_rdpe 0x80
#define perror_m_nds 0x100
#define perror_m_rto 0x200
#define perror_m_uecc 0x400
#define perror_m_cre 0x800
#define perror_m_addrl 0xFFFFFFFF0000UL
#define perror_m_addrh 0x7000000000000UL
#define perror_m_cmd 0xF0000000000000UL
#define perror_m_syn 0xFF00000000000000UL
union TPchipPERROR {
	struct  {
		unsigned int perror_v_lost : 1;
		unsigned perror_v_serr : 1;
		unsigned perror_v_perr : 1;
		unsigned perror_v_dcrto : 1;
		unsigned perror_v_sge : 1;
		unsigned perror_v_ape : 1;
		unsigned perror_v_ta : 1;
		unsigned perror_v_rdpe : 1;
		unsigned perror_v_nds : 1;
		unsigned perror_v_rto : 1;
		unsigned perror_v_uecc : 1;
		unsigned perror_v_cre : 1;
		unsigned perror_v_rsvd1 : 4;
		unsigned perror_v_addrl : 32;
		unsigned perror_v_addrh : 3;
		unsigned perror_v_rsvd2 : 1;
		unsigned perror_v_cmd : 4;
		unsigned perror_v_syn : 8;
	} perror_r_bits;
	int perror_q_whole [2];
};

/*
 * TSUNAMI Pchip Window Space Base Address register.
 */
#define wsba_m_ena 0x1
#define wsba_m_sg 0x2
#define wsba_m_ptp 0x4
#define wsba_m_addr 0xFFF00000
#define wmask_k_sz1gb 0x3FF00000
union TPchipWSBA {
	struct  {
		unsigned wsba_v_ena : 1;
		unsigned wsba_v_sg : 1;
		unsigned wsba_v_ptp : 1;
		unsigned wsba_v_rsvd1 : 17;
		unsigned wsba_v_addr : 12;
		unsigned wsba_v_rsvd2 : 32;
	} wsba_r_bits;
	int wsba_q_whole [2];
};

/*
 * TSUNAMI Pchip Control Register
 */
#define pctl_m_fdsc 0x1
#define pctl_m_fbtb 0x2
#define pctl_m_thdis 0x4
#define pctl_m_chaindis 0x8
#define pctl_m_tgtlat 0x10
#define pctl_m_hole 0x20
#define pctl_m_mwin 0x40
#define pctl_m_arbena 0x80
#define pctl_m_prigrp 0x7F00
#define pctl_m_ppri 0x8000
#define pctl_m_rsvd1 0x30000
#define pctl_m_eccen 0x40000
#define pctl_m_padm 0x80000
#define pctl_m_cdqmax 0xF00000
#define pctl_m_rev 0xFF000000
#define pctl_m_crqmax 0xF00000000UL
#define pctl_m_ptpmax 0xF000000000UL
#define pctl_m_pclkx 0x30000000000UL
#define pctl_m_fdsdis 0x40000000000UL
#define pctl_m_fdwdis 0x80000000000UL
#define pctl_m_ptevrfy 0x100000000000UL
#define pctl_m_rpp 0x200000000000UL
#define pctl_m_pid 0xC00000000000UL
#define pctl_m_rsvd2 0xFFFF000000000000UL

union TPchipPCTL {
	struct {
		unsigned pctl_v_fdsc : 1;
		unsigned pctl_v_fbtb : 1;
		unsigned pctl_v_thdis : 1;
		unsigned pctl_v_chaindis : 1;
		unsigned pctl_v_tgtlat : 1;
		unsigned pctl_v_hole : 1;
		unsigned pctl_v_mwin : 1;
		unsigned pctl_v_arbena : 1;
		unsigned pctl_v_prigrp : 7;
		unsigned pctl_v_ppri : 1;
		unsigned pctl_v_rsvd1 : 2;
		unsigned pctl_v_eccen : 1;
		unsigned pctl_v_padm : 1;
		unsigned pctl_v_cdqmax : 4;
		unsigned pctl_v_rev : 8;
		unsigned pctl_v_crqmax : 4;
		unsigned pctl_v_ptpmax : 4;
		unsigned pctl_v_pclkx : 2;
		unsigned pctl_v_fdsdis : 1;
		unsigned pctl_v_fdwdis : 1;
		unsigned pctl_v_ptevrfy : 1;
		unsigned pctl_v_rpp : 1;
		unsigned pctl_v_pid : 2;
		unsigned pctl_v_rsvd2 : 16;
	} pctl_r_bits;
	int pctl_q_whole [2];
};

/*
 * TSUNAMI Pchip Error Mask Register.
 */
#define perrmask_m_lost 0x1
#define perrmask_m_serr 0x2
#define perrmask_m_perr 0x4
#define perrmask_m_dcrto 0x8
#define perrmask_m_sge 0x10
#define perrmask_m_ape 0x20
#define perrmask_m_ta 0x40
#define perrmask_m_rdpe 0x80
#define perrmask_m_nds 0x100
#define perrmask_m_rto 0x200
#define perrmask_m_uecc 0x400
#define perrmask_m_cre 0x800
#define perrmask_m_rsvd 0xFFFFFFFFFFFFF000UL
union TPchipPERRMASK {
	struct  {
		unsigned int perrmask_v_lost : 1;
		unsigned perrmask_v_serr : 1;
		unsigned perrmask_v_perr : 1;
		unsigned perrmask_v_dcrto : 1;
		unsigned perrmask_v_sge : 1;
		unsigned perrmask_v_ape : 1;
		unsigned perrmask_v_ta : 1;
		unsigned perrmask_v_rdpe : 1;
		unsigned perrmask_v_nds : 1;
		unsigned perrmask_v_rto : 1;
		unsigned perrmask_v_uecc : 1;
		unsigned perrmask_v_cre : 1;
		unsigned perrmask_v_rsvd1 : 20;
		unsigned perrmask_v_rsvd2 : 32;
	} perrmask_r_bits;
	int perrmask_q_whole [2];
};

/*
 * Memory spaces:
 */
#define TSUNAMI_HOSE(h)		(((unsigned long)(h)) << 33)
#define TSUNAMI_BASE		(IDENT_ADDR + TS_BIAS)

#define TSUNAMI_MEM(h)		(TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x000000000UL)
#define _TSUNAMI_IACK_SC(h)	(TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1F8000000UL)
#define TSUNAMI_IO(h)		(TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1FC000000UL)
#define TSUNAMI_CONF(h)		(TSUNAMI_BASE+TSUNAMI_HOSE(h) + 0x1FE000000UL)

#define TSUNAMI_IACK_SC		_TSUNAMI_IACK_SC(0) /* hack! */

/*
 * The canonical non-remaped I/O and MEM addresses have these values
 * subtracted out.  This is arranged so that folks manipulating ISA
 * devices can use their familiar numbers and have them map to bus 0.
 */

#define TSUNAMI_IO_BIAS          TSUNAMI_IO(0)
#define TSUNAMI_MEM_BIAS         TSUNAMI_MEM(0)

/* The IO address space is larger than 0xffff */
#define TSUNAMI_IO_SPACE	(TSUNAMI_CONF(0) - TSUNAMI_IO(0))

/* Offset between ram physical addresses and pci64 DAC bus addresses.  */
#define TSUNAMI_DAC_OFFSET	(1UL << 40)

/*
 * Data structure for handling TSUNAMI machine checks:
 */
struct el_TSUNAMI_sysdata_mcheck {
};

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * I/O functions:
 *
 * TSUNAMI, the 21??? PCI/memory support chipset for the EV6 (21264)
 * can only use linear accesses to get at PCI memory and I/O spaces.
 */

/*
 * Memory functions.  all accesses are done through linear space.
 */
extern void __iomem *tsunami_ioportmap(unsigned long addr);
extern void __iomem *tsunami_ioremap(unsigned long addr, unsigned long size);
__EXTERN_INLINE int tsunami_is_ioaddr(unsigned long addr)
{
	return addr >= TSUNAMI_BASE;
}

__EXTERN_INLINE int tsunami_is_mmio(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long) xaddr;
	return (addr & 0x100000000UL) == 0;
}

#undef __IO_PREFIX
#define __IO_PREFIX		tsunami
#define tsunami_trivial_rw_bw	1
#define tsunami_trivial_rw_lq	1
#define tsunami_trivial_io_bw	1
#define tsunami_trivial_io_lq	1
#define tsunami_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_TSUNAMI__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_WILDFIRE__H__
#define __ALPHA_WILDFIRE__H__

#include <linux/types.h>
#include <asm/compiler.h>

#define WILDFIRE_MAX_QBB	8	/* more than 8 requires other mods */
#define WILDFIRE_PCA_PER_QBB	4
#define WILDFIRE_IRQ_PER_PCA	64

#define WILDFIRE_NR_IRQS \
  (WILDFIRE_MAX_QBB * WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)

extern unsigned char wildfire_hard_qbb_map[WILDFIRE_MAX_QBB];
extern unsigned char wildfire_soft_qbb_map[WILDFIRE_MAX_QBB];
#define QBB_MAP_EMPTY	0xff

extern unsigned long wildfire_hard_qbb_mask;
extern unsigned long wildfire_soft_qbb_mask;
extern unsigned long wildfire_gp_mask;
extern unsigned long wildfire_hs_mask;
extern unsigned long wildfire_iop_mask;
extern unsigned long wildfire_ior_mask;
extern unsigned long wildfire_pca_mask;
extern unsigned long wildfire_cpu_mask;
extern unsigned long wildfire_mem_mask;

#define WILDFIRE_QBB_EXISTS(qbbno) (wildfire_soft_qbb_mask & (1 << (qbbno)))

#define WILDFIRE_MEM_EXISTS(qbbno) (wildfire_mem_mask & (0xf << ((qbbno) << 2)))

#define WILDFIRE_PCA_EXISTS(qbbno, pcano) \
		(wildfire_pca_mask & (1 << (((qbbno) << 2) + (pcano))))

typedef struct {
	volatile unsigned long csr __attribute__((aligned(64)));
} wildfire_64;

typedef struct {
	volatile unsigned long csr __attribute__((aligned(256)));
} wildfire_256;

typedef struct {
	volatile unsigned long csr __attribute__((aligned(2048)));
} wildfire_2k;

typedef struct {
	wildfire_64	qsd_whami;
	wildfire_64	qsd_rev;
	wildfire_64	qsd_port_present;
	wildfire_64	qsd_port_active;
	wildfire_64	qsd_fault_ena;
	wildfire_64	qsd_cpu_int_ena;
	wildfire_64	qsd_mem_config;
	wildfire_64	qsd_err_sum;
	wildfire_64	ce_sum[4];
	wildfire_64	dev_init[4];
	wildfire_64	it_int[4];
	wildfire_64	ip_int[4];
	wildfire_64	uce_sum[4];
	wildfire_64	se_sum__non_dev_int[4];
	wildfire_64	scratch[4];
	wildfire_64	qsd_timer;
	wildfire_64	qsd_diag;
} wildfire_qsd;

typedef struct {
	wildfire_256	qsd_whami;
	wildfire_256	__pad1;
	wildfire_256	ce_sum;
	wildfire_256	dev_init;
	wildfire_256	it_int;
	wildfire_256	ip_int;
	wildfire_256	uce_sum;
	wildfire_256	se_sum;
} wildfire_fast_qsd;

typedef struct {
	wildfire_2k	qsa_qbb_id;
	wildfire_2k	__pad1;
	wildfire_2k	qsa_port_ena;
	wildfire_2k	qsa_scratch;
	wildfire_2k	qsa_config[5];
	wildfire_2k	qsa_ref_int;
	wildfire_2k	qsa_qbb_pop[2];
	wildfire_2k	qsa_dtag_fc;
	wildfire_2k	__pad2[3];
	wildfire_2k	qsa_diag;
	wildfire_2k	qsa_diag_lock[4];
	wildfire_2k	__pad3[11];
	wildfire_2k	qsa_cpu_err_sum;
	wildfire_2k	qsa_misc_err_sum;
	wildfire_2k	qsa_tmo_err_sum;
	wildfire_2k	qsa_err_ena;
	wildfire_2k	qsa_tmo_config;
	wildfire_2k	qsa_ill_cmd_err_sum;
	wildfire_2k	__pad4[26];
	wildfire_2k	qsa_busy_mask;
	wildfire_2k	qsa_arr_valid;
	wildfire_2k	__pad5[2];
	wildfire_2k	qsa_port_map[4];
	wildfire_2k	qsa_arr_addr[8];
	wildfire_2k	qsa_arr_mask[8];
} wildfire_qsa;

typedef struct {
	wildfire_64	ioa_config;
	wildfire_64	iod_config;
	wildfire_64	iop_switch_credits;
	wildfire_64	__pad1;
	wildfire_64	iop_hose_credits;
	wildfire_64	__pad2[11];
	struct {
		wildfire_64	__pad3;
		wildfire_64	init;
	} iop_hose[4];
	wildfire_64	ioa_hose_0_ctrl;
	wildfire_64	iod_hose_0_ctrl;
	wildfire_64	ioa_hose_1_ctrl;
	wildfire_64	iod_hose_1_ctrl;
	wildfire_64	ioa_hose_2_ctrl;
	wildfire_64	iod_hose_2_ctrl;
	wildfire_64	ioa_hose_3_ctrl;
	wildfire_64	iod_hose_3_ctrl;
	struct {
		wildfire_64	target;
		wildfire_64	__pad4;
	} iop_dev_int[4];

	wildfire_64	iop_err_int_target;
	wildfire_64	__pad5[7];
	wildfire_64	iop_qbb_err_sum;
	wildfire_64	__pad6;
	wildfire_64	iop_qbb_se_sum;
	wildfire_64	__pad7;
	wildfire_64	ioa_err_sum;
	wildfire_64	iod_err_sum;
	wildfire_64	__pad8[4];
	wildfire_64	ioa_diag_force_err;
	wildfire_64	iod_diag_force_err;
	wildfire_64	__pad9[4];
	wildfire_64	iop_diag_send_err_int;
	wildfire_64	__pad10[15];
	wildfire_64	ioa_scratch;
	wildfire_64	iod_scratch;
} wildfire_iop;

typedef struct {
	wildfire_2k	gpa_qbb_map[4];
	wildfire_2k	gpa_mem_pop_map;
	wildfire_2k	gpa_scratch;
	wildfire_2k	gpa_diag;
	wildfire_2k	gpa_config_0;
	wildfire_2k	__pad1;
	wildfire_2k	gpa_init_id;
	wildfire_2k	gpa_config_2;
	/* not complete */
} wildfire_gp;

typedef struct {
	wildfire_64	pca_what_am_i;
	wildfire_64	pca_err_sum;
	wildfire_64	pca_diag_force_err;
	wildfire_64	pca_diag_send_err_int;
	wildfire_64	pca_hose_credits;
	wildfire_64	pca_scratch;
	wildfire_64	pca_micro_addr;
	wildfire_64	pca_micro_data;
	wildfire_64	pca_pend_int;
	wildfire_64	pca_sent_int;
	wildfire_64	__pad1;
	wildfire_64	pca_stdio_edge_level;
	wildfire_64	__pad2[52];
	struct {
		wildfire_64	target;
		wildfire_64	enable;
	} pca_int[4];
	wildfire_64	__pad3[56];
	wildfire_64	pca_alt_sent_int[32];
} wildfire_pca;

typedef struct {
	wildfire_64	ne_what_am_i;
	/* not complete */
} wildfire_ne;

typedef struct {
	wildfire_64	fe_what_am_i;
	/* not complete */
} wildfire_fe;

typedef struct {
	wildfire_64	pci_io_addr_ext;
	wildfire_64	pci_ctrl;
	wildfire_64	pci_err_sum;
	wildfire_64	pci_err_addr;
	wildfire_64	pci_stall_cnt;
	wildfire_64	pci_iack_special;
	wildfire_64	__pad1[2];
	wildfire_64	pci_pend_int;
	wildfire_64	pci_sent_int;
	wildfire_64	__pad2[54];
	struct {
		wildfire_64	wbase;
		wildfire_64	wmask;
		wildfire_64	tbase;
	} pci_window[4];
	wildfire_64	pci_flush_tlb;
	wildfire_64	pci_perf_mon;
} wildfire_pci;

#define WILDFIRE_ENTITY_SHIFT		18

#define WILDFIRE_GP_ENTITY		(0x10UL << WILDFIRE_ENTITY_SHIFT)
#define WILDFIRE_IOP_ENTITY		(0x08UL << WILDFIRE_ENTITY_SHIFT)
#define WILDFIRE_QSA_ENTITY		(0x04UL << WILDFIRE_ENTITY_SHIFT)
#define WILDFIRE_QSD_ENTITY_SLOW	(0x05UL << WILDFIRE_ENTITY_SHIFT)
#define WILDFIRE_QSD_ENTITY_FAST	(0x01UL << WILDFIRE_ENTITY_SHIFT)

#define WILDFIRE_PCA_ENTITY(pca)	((0xc|(pca))<<WILDFIRE_ENTITY_SHIFT)

#define WILDFIRE_BASE		(IDENT_ADDR | (1UL << 40))

#define WILDFIRE_QBB_MASK	0x0fUL	/* for now, only 4 bits/16 QBBs */

#define WILDFIRE_QBB(q)		((~((long)(q)) & WILDFIRE_QBB_MASK) << 36)
#define WILDFIRE_HOSE(h)	((long)(h) << 33)

#define WILDFIRE_QBB_IO(q)	(WILDFIRE_BASE | WILDFIRE_QBB(q))
#define WILDFIRE_QBB_HOSE(q,h)	(WILDFIRE_QBB_IO(q) | WILDFIRE_HOSE(h))

#define WILDFIRE_MEM(q,h)	(WILDFIRE_QBB_HOSE(q,h) | 0x000000000UL)
#define WILDFIRE_CONF(q,h)	(WILDFIRE_QBB_HOSE(q,h) | 0x1FE000000UL)
#define WILDFIRE_IO(q,h)	(WILDFIRE_QBB_HOSE(q,h) | 0x1FF000000UL)

#define WILDFIRE_qsd(q) \
 ((wildfire_qsd *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSD_ENTITY_SLOW|(((1UL<<13)-1)<<23)))

#define WILDFIRE_fast_qsd() \
 ((wildfire_fast_qsd *)(WILDFIRE_QBB_IO(0)|WILDFIRE_QSD_ENTITY_FAST|(((1UL<<13)-1)<<23)))

#define WILDFIRE_qsa(q) \
 ((wildfire_qsa *)(WILDFIRE_QBB_IO(q)|WILDFIRE_QSA_ENTITY|(((1UL<<13)-1)<<23)))

#define WILDFIRE_iop(q) \
 ((wildfire_iop *)(WILDFIRE_QBB_IO(q)|WILDFIRE_IOP_ENTITY|(((1UL<<13)-1)<<23)))

#define WILDFIRE_gp(q) \
 ((wildfire_gp *)(WILDFIRE_QBB_IO(q)|WILDFIRE_GP_ENTITY|(((1UL<<13)-1)<<23)))

#define WILDFIRE_pca(q,pca) \
 ((wildfire_pca *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)))

#define WILDFIRE_ne(q,pca) \
 ((wildfire_ne *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(1UL<<16)))

#define WILDFIRE_fe(q,pca) \
 ((wildfire_fe *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(pca)|(((1UL<<13)-1)<<23)|(3UL<<15)))

#define WILDFIRE_pci(q,h) \
 ((wildfire_pci *)(WILDFIRE_QBB_IO(q)|WILDFIRE_PCA_ENTITY(((h)&6)>>1)|((((h)&1)|2)<<16)|(((1UL<<13)-1)<<23)))

#define WILDFIRE_IO_BIAS        WILDFIRE_IO(0,0)
#define WILDFIRE_MEM_BIAS       WILDFIRE_MEM(0,0) /* ??? */

/* The IO address space is larger than 0xffff */
#define WILDFIRE_IO_SPACE	(8UL*1024*1024)

#ifdef __KERNEL__

#ifndef __EXTERN_INLINE
#define __EXTERN_INLINE extern inline
#define __IO_EXTERN_INLINE
#endif

/*
 * Memory functions.  all accesses are done through linear space.
 */

__EXTERN_INLINE void __iomem *wildfire_ioportmap(unsigned long addr)
{
	return (void __iomem *)(addr + WILDFIRE_IO_BIAS);
}

__EXTERN_INLINE void __iomem *wildfire_ioremap(unsigned long addr,
					       unsigned long size)
{
	return (void __iomem *)(addr + WILDFIRE_MEM_BIAS);
}

__EXTERN_INLINE int wildfire_is_ioaddr(unsigned long addr)
{
	return addr >= WILDFIRE_BASE;
}

__EXTERN_INLINE int wildfire_is_mmio(const volatile void __iomem *xaddr)
{
	unsigned long addr = (unsigned long)xaddr;
	return (addr & 0x100000000UL) == 0;
}

#undef __IO_PREFIX
#define __IO_PREFIX			wildfire
#define wildfire_trivial_rw_bw		1
#define wildfire_trivial_rw_lq		1
#define wildfire_trivial_io_bw		1
#define wildfire_trivial_io_lq		1
#define wildfire_trivial_iounmap	1
#include <asm/io_trivial.h>

#ifdef __IO_EXTERN_INLINE
#undef __EXTERN_INLINE
#undef __IO_EXTERN_INLINE
#endif

#endif /* __KERNEL__ */

#endif /* __ALPHA_WILDFIRE__H__ */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ALPHA_DELAY_H
#define __ALPHA_DELAY_H

extern void __delay(int loops);
extern void udelay(unsigned long usecs);

extern void ndelay(unsigned long nsecs);
#define ndelay ndelay

#endif /* defined(__ALPHA_DELAY_H) */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Arch specific extensions to struct device
 */
#include <asm-generic/device.h>


code: #include <asm-generic/div64.h>


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ALPHA_DMA_MAPPING_H
#define _ALPHA_DMA_MAPPING_H

extern const struct dma_map_ops alpha_pci_ops;

static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
{
#ifdef CONFIG_ALPHA_JENSEN
	return NULL;
#else
	return &alpha_pci_ops;
#endif
}

#endif	/* _ALPHA_DMA_MAPPING_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * include/asm-alpha/dma.h
 *
 * This is essentially the same as the i386 DMA stuff, as the AlphaPCs
 * use ISA-compatible dma.  The only extension is support for high-page
 * registers that allow to set the top 8 bits of a 32-bit DMA address.
 * This register should be written last when setting up a DMA address
 * as this will also enable DMA across 64 KB boundaries.
 */

/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
 * linux/include/asm/dma.h: Defines for using and allocating dma channels.
 * Written by Hennus Bergman, 1992.
 * High DMA channel support & info by Hannu Savolainen
 * and John Boyd, Nov. 1992.
 */

#ifndef _ASM_DMA_H
#define _ASM_DMA_H

#include <linux/spinlock.h>
#include <asm/io.h>

#define dma_outb	outb
#define dma_inb		inb

/*
 * NOTES about DMA transfers:
 *
 *  controller 1: channels 0-3, byte operations, ports 00-1F
 *  controller 2: channels 4-7, word operations, ports C0-DF
 *
 *  - ALL registers are 8 bits only, regardless of transfer size
 *  - channel 4 is not used - cascades 1 into 2.
 *  - channels 0-3 are byte - addresses/counts are for physical bytes
 *  - channels 5-7 are word - addresses/counts are for physical words
 *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
 *  - transfer count loaded to registers is 1 less than actual count
 *  - controller 2 offsets are all even (2x offsets for controller 1)
 *  - page registers for 5-7 don't use data bit 0, represent 128K pages
 *  - page registers for 0-3 use bit 0, represent 64K pages
 *
 * DMA transfers are limited to the lower 16MB of _physical_ memory.
 * Note that addresses loaded into registers must be _physical_ addresses,
 * not logical addresses (which may differ if paging is active).
 *
 *  Address mapping for channels 0-3:
 *
 *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
 *    |  ...  |   |  ... |   |  ... |
 *    |  ...  |   |  ... |   |  ... |
 *    |  ...  |   |  ... |   |  ... |
 *   P7  ...  P0  A7 ... A0  A7 ... A0
 * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
 *
 *  Address mapping for channels 5-7:
 *
 *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
 *    |  ...  |   \   \   ... \  \  \  ... \  \
 *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
 *    |  ...  |     \   \   ... \  \  \  ... \
 *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0
 * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
 *
 * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
 * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
 * the hardware level, so odd-byte transfers aren't possible).
 *
 * Transfer count (_not # bytes_) is limited to 64K, represented as actual
 * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
 * and up to 128K bytes may be transferred on channels 5-7 in one operation.
 *
 */

#define MAX_DMA_CHANNELS	8

/*
  ISA DMA limitations on Alpha platforms,

  These may be due to SIO (PCI<->ISA bridge) chipset limitation, or
  just a wiring limit.
*/

/* The maximum address for ISA DMA transfer on Alpha XL, due to an
   hardware SIO limitation, is 64MB.
*/
#define ALPHA_XL_MAX_ISA_DMA_ADDRESS		0x04000000UL

/* The maximum address for ISA DMA transfer on RUFFIAN,
   due to an hardware SIO limitation, is 16MB.
*/
#define ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS	0x01000000UL

/* The maximum address for ISA DMA transfer on SABLE, and some ALCORs,
   due to an hardware SIO chip limitation, is 2GB.
*/
#define ALPHA_SABLE_MAX_ISA_DMA_ADDRESS		0x80000000UL
#define ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS		0x80000000UL

/*
  Maximum address for all the others is the complete 32-bit bus
  address space.
*/
#define ALPHA_MAX_ISA_DMA_ADDRESS		0x100000000UL

#ifdef CONFIG_ALPHA_GENERIC
# define MAX_ISA_DMA_ADDRESS		(alpha_mv.max_isa_dma_address)
#else
# if defined(CONFIG_ALPHA_XL)
#  define MAX_ISA_DMA_ADDRESS		ALPHA_XL_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_RUFFIAN)
#  define MAX_ISA_DMA_ADDRESS		ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_SABLE)
#  define MAX_ISA_DMA_ADDRESS		ALPHA_SABLE_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_ALCOR)
#  define MAX_ISA_DMA_ADDRESS		ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS
# else
#  define MAX_ISA_DMA_ADDRESS		ALPHA_MAX_ISA_DMA_ADDRESS
# endif
#endif

/* If we have the iommu, we don't have any address limitations on DMA.
   Otherwise (Nautilus, RX164), we have to have 0-16 Mb DMA zone
   like i386. */
#define MAX_DMA_ADDRESS		(alpha_mv.mv_pci_tbi ?	\
				 ~0UL : IDENT_ADDR + 0x01000000)

/* 8237 DMA controllers */
#define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
#define IO_DMA2_BASE	0xC0	/* 16 bit master DMA, ch 4(=slave input)..7 */

/* DMA controller registers */
#define DMA1_CMD_REG		0x08	/* command register (w) */
#define DMA1_STAT_REG		0x08	/* status register (r) */
#define DMA1_REQ_REG            0x09    /* request register (w) */
#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
#define DMA1_MODE_REG		0x0B	/* mode register (w) */
#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
#define DMA1_EXT_MODE_REG	(0x400 | DMA1_MODE_REG)

#define DMA2_CMD_REG		0xD0	/* command register (w) */
#define DMA2_STAT_REG		0xD0	/* status register (r) */
#define DMA2_REQ_REG            0xD2    /* request register (w) */
#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
#define DMA2_MODE_REG		0xD6	/* mode register (w) */
#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
#define DMA2_EXT_MODE_REG	(0x400 | DMA2_MODE_REG)

#define DMA_ADDR_0              0x00    /* DMA address registers */
#define DMA_ADDR_1              0x02
#define DMA_ADDR_2              0x04
#define DMA_ADDR_3              0x06
#define DMA_ADDR_4              0xC0
#define DMA_ADDR_5              0xC4
#define DMA_ADDR_6              0xC8
#define DMA_ADDR_7              0xCC

#define DMA_CNT_0               0x01    /* DMA count registers */
#define DMA_CNT_1               0x03
#define DMA_CNT_2               0x05
#define DMA_CNT_3               0x07
#define DMA_CNT_4               0xC2
#define DMA_CNT_5               0xC6
#define DMA_CNT_6               0xCA
#define DMA_CNT_7               0xCE

#define DMA_PAGE_0              0x87    /* DMA page registers */
#define DMA_PAGE_1              0x83
#define DMA_PAGE_2              0x81
#define DMA_PAGE_3              0x82
#define DMA_PAGE_5              0x8B
#define DMA_PAGE_6              0x89
#define DMA_PAGE_7              0x8A

#define DMA_HIPAGE_0		(0x400 | DMA_PAGE_0)
#define DMA_HIPAGE_1		(0x400 | DMA_PAGE_1)
#define DMA_HIPAGE_2		(0x400 | DMA_PAGE_2)
#define DMA_HIPAGE_3		(0x400 | DMA_PAGE_3)
#define DMA_HIPAGE_4		(0x400 | DMA_PAGE_4)
#define DMA_HIPAGE_5		(0x400 | DMA_PAGE_5)
#define DMA_HIPAGE_6		(0x400 | DMA_PAGE_6)
#define DMA_HIPAGE_7		(0x400 | DMA_PAGE_7)

#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */

#define DMA_AUTOINIT	0x10

extern spinlock_t  dma_spin_lock;

static __inline__ unsigned long claim_dma_lock(void)
{
	unsigned long flags;
	spin_lock_irqsave(&dma_spin_lock, flags);
	return flags;
}

static __inline__ void release_dma_lock(unsigned long flags)
{
	spin_unlock_irqrestore(&dma_spin_lock, flags);
}

/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
	if (dmanr<=3)
		dma_outb(dmanr,  DMA1_MASK_REG);
	else
		dma_outb(dmanr & 3,  DMA2_MASK_REG);
}

static __inline__ void disable_dma(unsigned int dmanr)
{
	if (dmanr<=3)
		dma_outb(dmanr | 4,  DMA1_MASK_REG);
	else
		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
}

/* Clear the 'DMA Pointer Flip Flop'.
 * Write 0 for LSB/MSB, 1 for MSB/LSB access.
 * Use this once to initialize the FF to a known state.
 * After that, keep track of it. :-)
 * --- In order to do that, the DMA routines below should ---
 * --- only be used while interrupts are disabled! ---
 */
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
	if (dmanr<=3)
		dma_outb(0,  DMA1_CLEAR_FF_REG);
	else
		dma_outb(0,  DMA2_CLEAR_FF_REG);
}

/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
	if (dmanr<=3)
		dma_outb(mode | dmanr,  DMA1_MODE_REG);
	else
		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
}

/* set extended mode for a specific DMA channel */
static __inline__ void set_dma_ext_mode(unsigned int dmanr, char ext_mode)
{
	if (dmanr<=3)
		dma_outb(ext_mode | dmanr,  DMA1_EXT_MODE_REG);
	else
		dma_outb(ext_mode | (dmanr&3),  DMA2_EXT_MODE_REG);
}

/* Set only the page register bits of the transfer address.
 * This is used for successive transfers when we know the contents of
 * the lower 16 bits of the DMA current address register.
 */
static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr)
{
	switch(dmanr) {
		case 0:
			dma_outb(pagenr, DMA_PAGE_0);
			dma_outb((pagenr >> 8), DMA_HIPAGE_0);
			break;
		case 1:
			dma_outb(pagenr, DMA_PAGE_1);
			dma_outb((pagenr >> 8), DMA_HIPAGE_1);
			break;
		case 2:
			dma_outb(pagenr, DMA_PAGE_2);
			dma_outb((pagenr >> 8), DMA_HIPAGE_2);
			break;
		case 3:
			dma_outb(pagenr, DMA_PAGE_3);
			dma_outb((pagenr >> 8), DMA_HIPAGE_3);
			break;
		case 5:
			dma_outb(pagenr & 0xfe, DMA_PAGE_5);
			dma_outb((pagenr >> 8), DMA_HIPAGE_5);
			break;
		case 6:
			dma_outb(pagenr & 0xfe, DMA_PAGE_6);
			dma_outb((pagenr >> 8), DMA_HIPAGE_6);
			break;
		case 7:
			dma_outb(pagenr & 0xfe, DMA_PAGE_7);
			dma_outb((pagenr >> 8), DMA_HIPAGE_7);
			break;
	}
}

/* Set transfer address & page bits for specific DMA channel.
 * Assumes dma flipflop is clear.
 */
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
	if (dmanr <= 3)  {
	    dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
	}  else  {
	    dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
	    dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
	}
	set_dma_page(dmanr, a>>16);	/* set hipage last to enable 32-bit mode */
}

/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
 * a specific DMA channel.
 * You must ensure the parameters are valid.
 * NOTE: from a manual: "the number of transfers is one more
 * than the initial word count"! This is taken into account.
 * Assumes dma flip-flop is clear.
 * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
 */
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
        count--;
	if (dmanr <= 3)  {
	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
        } else {
	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
        }
}

/* Get DMA residue count. After a DMA transfer, this
 * should return zero. Reading this while a DMA transfer is
 * still in progress will return unpredictable results.
 * If called before the channel has been used, it may return 1.
 * Otherwise, it returns the number of _bytes_ left to transfer.
 *
 * Assumes DMA flip-flop is clear.
 */
static __inline__ int get_dma_residue(unsigned int dmanr)
{
	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;

	/* using short to get 16-bit wrap around */
	unsigned short count;

	count = 1 + dma_inb(io_port);
	count += dma_inb(io_port) << 8;

	return (dmanr<=3)? count : (count<<1);
}

/* These are in kernel/dma.c: */
extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
extern void free_dma(unsigned int dmanr);	/* release it again */
#define KERNEL_HAVE_CHECK_DMA
extern int check_dma(unsigned int dmanr);

#endif /* _ASM_DMA_H */