tioca_provider.h 6.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
 */

#ifndef _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
#define _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H

#include <asm/sn/tioca.h>

/*
 * WAR enables
 * Defines for individual WARs. Each is a bitmask of applicable
 * part revision numbers. (1 << 1) == rev A, (1 << 2) == rev B,
 * (3 << 1) == (rev A or rev B), etc
 */

#define TIOCA_WAR_ENABLED(pv, tioca_common) \
	((1 << tioca_common->ca_rev) & pv)

  /* TIO:ICE:FRZ:Freezer loses a PIO data ucred on PIO RD RSP with CW error */
#define PV907908 (1 << 1)
  /* ATI config space problems after BIOS execution starts */
#define PV908234 (1 << 1)
  /* CA:AGPDMA write request data mismatch with ABC1CL merge */
#define PV895469 (1 << 1)
A
Adrian Bunk 已提交
30
  /* TIO:CA TLB invalidate of written GART entries possibly not occurring in CA*/
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#define PV910244 (1 << 1)

struct tioca_dmamap{
	struct list_head	cad_list;	/* headed by ca_list */

	dma_addr_t		cad_dma_addr;	/* Linux dma handle */
	uint			cad_gart_entry; /* start entry in ca_gart_pagemap */
	uint			cad_gart_size;	/* #entries for this map */
};

/*
 * Kernel only fields.  Prom may look at this stuff for debugging only.
 * Access this structure through the ca_kernel_private ptr.
 */

struct tioca_common ;

struct tioca_kernel {
	struct tioca_common	*ca_common;	/* tioca this belongs to */
	struct list_head	ca_list;	/* list of all ca's */
	struct list_head	ca_dmamaps;
	spinlock_t		ca_lock;	/* Kernel lock */
	cnodeid_t		ca_closest_node;
	struct list_head	*ca_devices;	/* bus->devices */

	/*
	 * General GART stuff
	 */
59 60 61 62 63 64 65 66
	u64	ca_ap_size;		/* size of aperature in bytes */
	u32	ca_gart_entries;	/* # u64 entries in gart */
	u32	ca_ap_pagesize; 	/* aperature page size in bytes */
	u64	ca_ap_bus_base; 	/* bus address of CA aperature */
	u64	ca_gart_size;		/* gart size in bytes */
	u64	*ca_gart;		/* gart table vaddr */
	u64	ca_gart_coretalk_addr;	/* gart coretalk addr */
	u8		ca_gart_iscoherent;	/* used in tioca_tlbflush */
67 68

	/* PCI GART convenience values */
69 70 71 72 73 74
	u64	ca_pciap_base;		/* pci aperature bus base address */
	u64	ca_pciap_size;		/* pci aperature size (bytes) */
	u64	ca_pcigart_base;	/* gfx GART bus base address */
	u64	*ca_pcigart;		/* gfx GART vm address */
	u32	ca_pcigart_entries;
	u32	ca_pcigart_start;	/* PCI start index in ca_gart */
75 76 77
	void		*ca_pcigart_pagemap;

	/* AGP GART convenience values */
78 79 80 81 82 83
	u64	ca_gfxap_base;		/* gfx aperature bus base address */
	u64	ca_gfxap_size;		/* gfx aperature size (bytes) */
	u64	ca_gfxgart_base;	/* gfx GART bus base address */
	u64	*ca_gfxgart;		/* gfx GART vm address */
	u32	ca_gfxgart_entries;
	u32	ca_gfxgart_start;	/* agpgart start index in ca_gart */
84 85 86 87 88 89 90 91 92 93 94 95
};

/*
 * Common tioca info shared between kernel and prom
 *
 * DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES
 * TO THE PROM VERSION.
 */

struct tioca_common {
	struct pcibus_bussoft	ca_common;	/* common pciio header */

96 97
	u32		ca_rev;
	u32		ca_closest_nasid;
98

99 100
	u64		ca_prom_private;
	u64		ca_kernel_private;
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
};

/**
 * tioca_paddr_to_gart - Convert an SGI coretalk address to a CA GART entry
 * @paddr: page address to convert
 *
 * Convert a system [coretalk] address to a GART entry.  GART entries are
 * formed using the following:
 *
 *     data = ( (1<<63) |  ( (REMAP_NODE_ID << 40) | (MD_CHIPLET_ID << 38) | 
 * (REMAP_SYS_ADDR) ) >> 12 )
 *
 * DATA written to 1 GART TABLE Entry in system memory is remapped system
 * addr for 1 page 
 *
 * The data is for coretalk address format right shifted 12 bits with a
 * valid bit.
 *
 *	GART_TABLE_ENTRY [ 25:0 ]  -- REMAP_SYS_ADDRESS[37:12].
 *	GART_TABLE_ENTRY [ 27:26 ] -- SHUB MD chiplet id.
 *	GART_TABLE_ENTRY [ 41:28 ] -- REMAP_NODE_ID.
 *	GART_TABLE_ENTRY [ 63 ]    -- Valid Bit 
 */
static inline u64
tioca_paddr_to_gart(unsigned long paddr)
{
	/*
	 * We are assuming right now that paddr already has the correct
	 * format since the address from xtalk_dmaXXX should already have
	 * NODE_ID, CHIPLET_ID, and SYS_ADDR in the correct locations.
	 */

	return ((paddr) >> 12) | (1UL << 63);
}

/**
 * tioca_physpage_to_gart - Map a host physical page for SGI CA based DMA
 * @page_addr: system page address to map
 */

static inline unsigned long
142
tioca_physpage_to_gart(u64 page_addr)
143
{
144
	u64 coretalk_addr;
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

	coretalk_addr = PHYS_TO_TIODMA(page_addr);
	if (!coretalk_addr) {
		return 0;
	}

	return tioca_paddr_to_gart(coretalk_addr);
}

/**
 * tioca_tlbflush - invalidate cached SGI CA GART TLB entries
 * @tioca_kernel: CA context 
 *
 * Invalidate tlb entries for a given CA GART.  Main complexity is to account
 * for revA bug.
 */
static inline void
tioca_tlbflush(struct tioca_kernel *tioca_kernel)
{
164
	volatile u64 tmp;
A
Al Viro 已提交
165
	volatile struct tioca __iomem *ca_base;
166 167 168
	struct tioca_common *tioca_common;

	tioca_common = tioca_kernel->ca_common;
A
Al Viro 已提交
169
	ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184

	/*
	 * Explicit flushes not needed if GART is in cached mode
	 */
	if (tioca_kernel->ca_gart_iscoherent) {
		if (TIOCA_WAR_ENABLED(PV910244, tioca_common)) {
			/*
			 * PV910244:  RevA CA needs explicit flushes.
			 * Need to put GART into uncached mode before
			 * flushing otherwise the explicit flush is ignored.
			 *
			 * Alternate WAR would be to leave GART cached and
			 * touch every CL aligned GART entry.
			 */

185 186 187 188 189
			__sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
			__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
			__sn_setq_relaxed(&ca_base->ca_control2,
			    (0x2ull << CA_GART_MEM_PARAM_SHFT));
			tmp = __sn_readq_relaxed(&ca_base->ca_control2);
190 191 192 193 194 195 196 197 198
		}

		return;
	}

	/*
	 * Gart in uncached mode ... need an explicit flush.
	 */

199 200
	__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
	tmp = __sn_readq_relaxed(&ca_base->ca_control2);
201 202
}

203
extern u32	tioca_gart_found;
204
extern struct list_head tioca_list;
205 206 207
extern int tioca_init_provider(void);
extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
#endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */