1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
7 */
8
9#ifndef _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
10#define _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
11
12#include <asm/sn/tioca.h>
13
14/*
15 * WAR enables
16 * Defines for individual WARs. Each is a bitmask of applicable
17 * part revision numbers. (1 << 1) == rev A, (1 << 2) == rev B,
18 * (3 << 1) == (rev A or rev B), etc
19 */
20
21#define TIOCA_WAR_ENABLED(pv, tioca_common) \
22	((1 << tioca_common->ca_rev) & pv)
23
24  /* TIO:ICE:FRZ:Freezer loses a PIO data ucred on PIO RD RSP with CW error */
25#define PV907908 (1 << 1)
26  /* ATI config space problems after BIOS execution starts */
27#define PV908234 (1 << 1)
28  /* CA:AGPDMA write request data mismatch with ABC1CL merge */
29#define PV895469 (1 << 1)
30  /* TIO:CA TLB invalidate of written GART entries possibly not occurring in CA*/
31#define PV910244 (1 << 1)
32
33struct tioca_dmamap{
34	struct list_head	cad_list;	/* headed by ca_list */
35
36	dma_addr_t		cad_dma_addr;	/* Linux dma handle */
37	uint			cad_gart_entry; /* start entry in ca_gart_pagemap */
38	uint			cad_gart_size;	/* #entries for this map */
39};
40
41/*
42 * Kernel only fields.  Prom may look at this stuff for debugging only.
43 * Access this structure through the ca_kernel_private ptr.
44 */
45
46struct tioca_common ;
47
48struct tioca_kernel {
49	struct tioca_common	*ca_common;	/* tioca this belongs to */
50	struct list_head	ca_list;	/* list of all ca's */
51	struct list_head	ca_dmamaps;
52	spinlock_t		ca_lock;	/* Kernel lock */
53	cnodeid_t		ca_closest_node;
54	struct list_head	*ca_devices;	/* bus->devices */
55
56	/*
57	 * General GART stuff
58	 */
59	u64	ca_ap_size;		/* size of aperature in bytes */
60	u32	ca_gart_entries;	/* # u64 entries in gart */
61	u32	ca_ap_pagesize; 	/* aperature page size in bytes */
62	u64	ca_ap_bus_base; 	/* bus address of CA aperature */
63	u64	ca_gart_size;		/* gart size in bytes */
64	u64	*ca_gart;		/* gart table vaddr */
65	u64	ca_gart_coretalk_addr;	/* gart coretalk addr */
66	u8		ca_gart_iscoherent;	/* used in tioca_tlbflush */
67
68	/* PCI GART convenience values */
69	u64	ca_pciap_base;		/* pci aperature bus base address */
70	u64	ca_pciap_size;		/* pci aperature size (bytes) */
71	u64	ca_pcigart_base;	/* gfx GART bus base address */
72	u64	*ca_pcigart;		/* gfx GART vm address */
73	u32	ca_pcigart_entries;
74	u32	ca_pcigart_start;	/* PCI start index in ca_gart */
75	void		*ca_pcigart_pagemap;
76
77	/* AGP GART convenience values */
78	u64	ca_gfxap_base;		/* gfx aperature bus base address */
79	u64	ca_gfxap_size;		/* gfx aperature size (bytes) */
80	u64	ca_gfxgart_base;	/* gfx GART bus base address */
81	u64	*ca_gfxgart;		/* gfx GART vm address */
82	u32	ca_gfxgart_entries;
83	u32	ca_gfxgart_start;	/* agpgart start index in ca_gart */
84};
85
86/*
87 * Common tioca info shared between kernel and prom
88 *
89 * DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES
90 * TO THE PROM VERSION.
91 */
92
93struct tioca_common {
94	struct pcibus_bussoft	ca_common;	/* common pciio header */
95
96	u32		ca_rev;
97	u32		ca_closest_nasid;
98
99	u64		ca_prom_private;
100	u64		ca_kernel_private;
101};
102
103/**
104 * tioca_paddr_to_gart - Convert an SGI coretalk address to a CA GART entry
105 * @paddr: page address to convert
106 *
107 * Convert a system [coretalk] address to a GART entry.  GART entries are
108 * formed using the following:
109 *
110 *     data = ( (1<<63) |  ( (REMAP_NODE_ID << 40) | (MD_CHIPLET_ID << 38) |
111 * (REMAP_SYS_ADDR) ) >> 12 )
112 *
113 * DATA written to 1 GART TABLE Entry in system memory is remapped system
114 * addr for 1 page
115 *
116 * The data is for coretalk address format right shifted 12 bits with a
117 * valid bit.
118 *
119 *	GART_TABLE_ENTRY [ 25:0 ]  -- REMAP_SYS_ADDRESS[37:12].
120 *	GART_TABLE_ENTRY [ 27:26 ] -- SHUB MD chiplet id.
121 *	GART_TABLE_ENTRY [ 41:28 ] -- REMAP_NODE_ID.
122 *	GART_TABLE_ENTRY [ 63 ]    -- Valid Bit
123 */
124static inline u64
125tioca_paddr_to_gart(unsigned long paddr)
126{
127	/*
128	 * We are assuming right now that paddr already has the correct
129	 * format since the address from xtalk_dmaXXX should already have
130	 * NODE_ID, CHIPLET_ID, and SYS_ADDR in the correct locations.
131	 */
132
133	return ((paddr) >> 12) | (1UL << 63);
134}
135
136/**
137 * tioca_physpage_to_gart - Map a host physical page for SGI CA based DMA
138 * @page_addr: system page address to map
139 */
140
141static inline unsigned long
142tioca_physpage_to_gart(u64 page_addr)
143{
144	u64 coretalk_addr;
145
146	coretalk_addr = PHYS_TO_TIODMA(page_addr);
147	if (!coretalk_addr) {
148		return 0;
149	}
150
151	return tioca_paddr_to_gart(coretalk_addr);
152}
153
154/**
155 * tioca_tlbflush - invalidate cached SGI CA GART TLB entries
156 * @tioca_kernel: CA context
157 *
158 * Invalidate tlb entries for a given CA GART.  Main complexity is to account
159 * for revA bug.
160 */
161static inline void
162tioca_tlbflush(struct tioca_kernel *tioca_kernel)
163{
164	volatile u64 tmp;
165	volatile struct tioca __iomem *ca_base;
166	struct tioca_common *tioca_common;
167
168	tioca_common = tioca_kernel->ca_common;
169	ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
170
171	/*
172	 * Explicit flushes not needed if GART is in cached mode
173	 */
174	if (tioca_kernel->ca_gart_iscoherent) {
175		if (TIOCA_WAR_ENABLED(PV910244, tioca_common)) {
176			/*
177			 * PV910244:  RevA CA needs explicit flushes.
178			 * Need to put GART into uncached mode before
179			 * flushing otherwise the explicit flush is ignored.
180			 *
181			 * Alternate WAR would be to leave GART cached and
182			 * touch every CL aligned GART entry.
183			 */
184
185			__sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
186			__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
187			__sn_setq_relaxed(&ca_base->ca_control2,
188			    (0x2ull << CA_GART_MEM_PARAM_SHFT));
189			tmp = __sn_readq_relaxed(&ca_base->ca_control2);
190		}
191
192		return;
193	}
194
195	/*
196	 * Gart in uncached mode ... need an explicit flush.
197	 */
198
199	__sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
200	tmp = __sn_readq_relaxed(&ca_base->ca_control2);
201}
202
203extern u32	tioca_gart_found;
204extern struct list_head tioca_list;
205extern int tioca_init_provider(void);
206extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
207#endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
208