blob: 9a820ac61be338347f23d5d939e009bce8d52a7d [file] [log] [blame]
Mark Maule9c90bdd2005-04-25 11:35:54 -07001/*
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)
Adrian Bunk80f72282006-06-30 18:27:16 +020030 /* TIO:CA TLB invalidate of written GART entries possibly not occurring in CA*/
Mark Maule9c90bdd2005-04-25 11:35:54 -070031#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 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080059 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 */
Mark Maule9c90bdd2005-04-25 11:35:54 -070067
68 /* PCI GART convenience values */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080069 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 */
Mark Maule9c90bdd2005-04-25 11:35:54 -070075 void *ca_pcigart_pagemap;
76
77 /* AGP GART convenience values */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080078 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 */
Mark Maule9c90bdd2005-04-25 11:35:54 -070084};
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
Prarit Bhargava53493dc2006-01-16 19:54:40 -080096 u32 ca_rev;
97 u32 ca_closest_nasid;
Mark Maule9c90bdd2005-04-25 11:35:54 -070098
Prarit Bhargava53493dc2006-01-16 19:54:40 -080099 u64 ca_prom_private;
100 u64 ca_kernel_private;
Mark Maule9c90bdd2005-04-25 11:35:54 -0700101};
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
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800142tioca_physpage_to_gart(u64 page_addr)
Mark Maule9c90bdd2005-04-25 11:35:54 -0700143{
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800144 u64 coretalk_addr;
Mark Maule9c90bdd2005-04-25 11:35:54 -0700145
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{
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800164 volatile u64 tmp;
Al Viroa9f627c2006-10-10 22:46:27 +0100165 volatile struct tioca __iomem *ca_base;
Mark Maule9c90bdd2005-04-25 11:35:54 -0700166 struct tioca_common *tioca_common;
167
168 tioca_common = tioca_kernel->ca_common;
Al Viroa9f627c2006-10-10 22:46:27 +0100169 ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
Mark Maule9c90bdd2005-04-25 11:35:54 -0700170
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
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500185 __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);
Mark Maule9c90bdd2005-04-25 11:35:54 -0700190 }
191
192 return;
193 }
194
195 /*
196 * Gart in uncached mode ... need an explicit flush.
197 */
198
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500199 __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
200 tmp = __sn_readq_relaxed(&ca_base->ca_control2);
Mark Maule9c90bdd2005-04-25 11:35:54 -0700201}
202
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800203extern u32 tioca_gart_found;
Prarit Bhargava92a582e2005-05-10 12:40:00 -0700204extern struct list_head tioca_list;
Mark Maule9c90bdd2005-04-25 11:35:54 -0700205extern 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 */