ext3: statfs speed up
[linux-2.6] / include / asm-ia64 / sn / tioca_provider.h
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
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
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
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 */