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 
33 struct 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 
46 struct tioca_common ;
47 
48 struct 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 
93 struct 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  */
124 static inline u64
tioca_paddr_to_gart(unsigned long paddr)125 tioca_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 
141 static inline unsigned long
tioca_physpage_to_gart(u64 page_addr)142 tioca_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  */
161 static inline void
tioca_tlbflush(struct tioca_kernel * tioca_kernel)162 tioca_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 
203 extern u32	tioca_gart_found;
204 extern struct list_head tioca_list;
205 extern int tioca_init_provider(void);
206 extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
207 #endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
208