2 * Transmeta's Efficeon AGPGART driver.
4 * Based upon a diff by Linus around November '02.
6 * Ported to the 2.6 kernel by Carlos Puchol <cpglinux@puchol.com>
7 * and H. Peter Anvin <hpa@transmeta.com>.
13 * - when compiled as a module, after loading the module,
14 * it will refuse to unload, indicating it is in use,
16 * - no s3 (suspend to ram) testing.
17 * - tested on the efficeon integrated nothbridge for tens
18 * of iterations of starting x and glxgears.
19 * - tested with radeon 9000 and radeon mobility m9 cards
20 * - tested with c3/c4 enabled (with the mobility m9 card)
23 #include <linux/module.h>
24 #include <linux/pci.h>
25 #include <linux/init.h>
26 #include <linux/agp_backend.h>
27 #include <linux/gfp.h>
28 #include <linux/page-flags.h>
33 * The real differences to the generic AGP code is
34 * in the GART mappings - a two-level setup with the
35 * first level being an on-chip 64-entry table.
37 * The page array is filled through the ATTPAGE register
38 * (Aperture Translation Table Page Register) at 0xB8. Bits:
39 * 31:20: physical page address
40 * 11:9: Page Attribute Table Index (PATI)
41 * must match the PAT index for the
42 * mapped pages (the 2nd level page table pages
43 * themselves should be just regular WB-cacheable,
44 * so this is normally zero.)
46 * 7:6: reserved, write as zero
47 * 5:0: GATT directory index: which 1st-level entry
49 * The Efficeon AGP spec requires pages to be WB-cacheable
50 * but to be explicitly CLFLUSH'd after any changes.
52 #define EFFICEON_ATTPAGE 0xb8
53 #define EFFICEON_L1_SIZE 64 /* Number of PDE pages */
55 #define EFFICEON_PATI (0 << 9)
56 #define EFFICEON_PRESENT (1 << 8)
58 static struct _efficeon_private
{
59 unsigned long l1_table
[EFFICEON_L1_SIZE
];
62 static struct gatt_mask efficeon_generic_masks
[] =
64 {.mask
= 0x00000001, .type
= 0}
67 static struct aper_size_info_lvl2 efficeon_generic_sizes
[4] =
76 * Control interfaces are largely identical to
77 * the legacy Intel 440BX..
80 static int efficeon_fetch_size(void)
84 struct aper_size_info_lvl2
*values
;
86 pci_read_config_word(agp_bridge
->dev
, INTEL_APSIZE
, &temp
);
87 values
= A_SIZE_LVL2(agp_bridge
->driver
->aperture_sizes
);
89 for (i
= 0; i
< agp_bridge
->driver
->num_aperture_sizes
; i
++) {
90 if (temp
== values
[i
].size_value
) {
91 agp_bridge
->previous_size
=
92 agp_bridge
->current_size
= (void *) (values
+ i
);
93 agp_bridge
->aperture_size_idx
= i
;
94 return values
[i
].size
;
101 static void efficeon_tlbflush(struct agp_memory
* mem
)
103 printk(KERN_DEBUG PFX
"efficeon_tlbflush()\n");
104 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2200);
105 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
108 static void efficeon_cleanup(void)
111 struct aper_size_info_lvl2
*previous_size
;
113 printk(KERN_DEBUG PFX
"efficeon_cleanup()\n");
114 previous_size
= A_SIZE_LVL2(agp_bridge
->previous_size
);
115 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp
);
116 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, temp
& ~(1 << 9));
117 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
118 previous_size
->size_value
);
121 static int efficeon_configure(void)
125 struct aper_size_info_lvl2
*current_size
;
127 printk(KERN_DEBUG PFX
"efficeon_configure()\n");
129 current_size
= A_SIZE_LVL2(agp_bridge
->current_size
);
132 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
133 current_size
->size_value
);
135 /* address to map to */
136 pci_read_config_dword(agp_bridge
->dev
, AGP_APBASE
, &temp
);
137 agp_bridge
->gart_bus_addr
= (temp
& PCI_BASE_ADDRESS_MEM_MASK
);
140 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
143 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp2
);
144 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
,
145 (temp2
& ~(1 << 10)) | (1 << 9) | (1 << 11));
146 /* clear any possible error conditions */
147 pci_write_config_byte(agp_bridge
->dev
, INTEL_ERRSTS
+ 1, 7);
151 static int efficeon_free_gatt_table(struct agp_bridge_data
*bridge
)
153 int index
, freed
= 0;
155 for (index
= 0; index
< EFFICEON_L1_SIZE
; index
++) {
156 unsigned long page
= efficeon_private
.l1_table
[index
];
158 efficeon_private
.l1_table
[index
] = 0;
159 ClearPageReserved(virt_to_page((char *)page
));
163 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table(%p, %02x, %08x)\n",
164 agp_bridge
->dev
, EFFICEON_ATTPAGE
, index
);
165 pci_write_config_dword(agp_bridge
->dev
,
166 EFFICEON_ATTPAGE
, index
);
168 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table() freed %d pages\n", freed
);
174 * Since we don't need contigious memory we just try
175 * to get the gatt table once
178 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
179 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
180 GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
181 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
183 #define GET_GATT(addr) (efficeon_private.gatt_pages[\
184 GET_PAGE_DIR_IDX(addr)]->remapped)
186 static int efficeon_create_gatt_table(struct agp_bridge_data
*bridge
)
189 const int pati
= EFFICEON_PATI
;
190 const int present
= EFFICEON_PRESENT
;
191 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
192 int num_entries
, l1_pages
;
194 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
196 printk(KERN_DEBUG PFX
"efficeon_create_gatt_table(%d)\n", num_entries
);
198 /* There are 2^10 PTE pages per PDE page */
199 BUG_ON(num_entries
& 0x3ff);
200 l1_pages
= num_entries
>> 10;
202 for (index
= 0 ; index
< l1_pages
; index
++) {
207 page
= efficeon_private
.l1_table
[index
];
210 page
= get_zeroed_page(GFP_KERNEL
);
212 efficeon_free_gatt_table(agp_bridge
);
215 SetPageReserved(virt_to_page((char *)page
));
217 for (offset
= 0; offset
< PAGE_SIZE
; offset
+= clflush_chunk
)
218 asm volatile("clflush %0" : : "m" (*(char *)(page
+offset
)));
220 efficeon_private
.l1_table
[index
] = page
;
222 value
= __pa(page
) | pati
| present
| index
;
224 pci_write_config_dword(agp_bridge
->dev
,
225 EFFICEON_ATTPAGE
, value
);
231 static int efficeon_insert_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
233 int i
, count
= mem
->page_count
, num_entries
;
234 unsigned int *page
, *last_page
;
235 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
236 const unsigned long clflush_mask
= ~(clflush_chunk
-1);
238 printk(KERN_DEBUG PFX
"efficeon_insert_memory(%lx, %d)\n", pg_start
, count
);
240 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
241 if ((pg_start
+ mem
->page_count
) > num_entries
)
243 if (type
!= 0 || mem
->type
!= 0)
246 if (mem
->is_flushed
== FALSE
) {
247 global_cache_flush();
248 mem
->is_flushed
= TRUE
;
252 for (i
= 0; i
< count
; i
++) {
253 int index
= pg_start
+ i
;
254 unsigned long insert
= mem
->memory
[i
];
256 page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
261 page
+= (index
& 0x3ff);
264 /* clflush is slow, so don't clflush until we have to */
266 ((unsigned long)page
^(unsigned long)last_page
) & clflush_mask
)
267 asm volatile("clflush %0" : : "m" (*last_page
));
273 asm volatile("clflush %0" : : "m" (*last_page
));
275 agp_bridge
->driver
->tlb_flush(mem
);
279 static int efficeon_remove_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
281 int i
, count
= mem
->page_count
, num_entries
;
283 printk(KERN_DEBUG PFX
"efficeon_remove_memory(%lx, %d)\n", pg_start
, count
);
285 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
287 if ((pg_start
+ mem
->page_count
) > num_entries
)
289 if (type
!= 0 || mem
->type
!= 0)
292 for (i
= 0; i
< count
; i
++) {
293 int index
= pg_start
+ i
;
294 unsigned int *page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
298 page
+= (index
& 0x3ff);
301 agp_bridge
->driver
->tlb_flush(mem
);
306 static struct agp_bridge_driver efficeon_driver
= {
307 .owner
= THIS_MODULE
,
308 .aperture_sizes
= efficeon_generic_sizes
,
309 .size_type
= LVL2_APER_SIZE
,
310 .num_aperture_sizes
= 4,
311 .configure
= efficeon_configure
,
312 .fetch_size
= efficeon_fetch_size
,
313 .cleanup
= efficeon_cleanup
,
314 .tlb_flush
= efficeon_tlbflush
,
315 .mask_memory
= agp_generic_mask_memory
,
316 .masks
= efficeon_generic_masks
,
317 .agp_enable
= agp_generic_enable
,
318 .cache_flush
= global_cache_flush
,
320 // Efficeon-specific GATT table setup / populate / teardown
321 .create_gatt_table
= efficeon_create_gatt_table
,
322 .free_gatt_table
= efficeon_free_gatt_table
,
323 .insert_memory
= efficeon_insert_memory
,
324 .remove_memory
= efficeon_remove_memory
,
325 .cant_use_aperture
= 0, // 1 might be faster?
328 .alloc_by_type
= agp_generic_alloc_by_type
,
329 .free_by_type
= agp_generic_free_by_type
,
330 .agp_alloc_page
= agp_generic_alloc_page
,
331 .agp_destroy_page
= agp_generic_destroy_page
,
335 static int agp_efficeon_resume(struct pci_dev
*pdev
)
337 printk(KERN_DEBUG PFX
"agp_efficeon_resume()\n");
338 return efficeon_configure();
341 static int __devinit
agp_efficeon_probe(struct pci_dev
*pdev
,
342 const struct pci_device_id
*ent
)
344 struct agp_bridge_data
*bridge
;
348 cap_ptr
= pci_find_capability(pdev
, PCI_CAP_ID_AGP
);
352 /* Probe for Efficeon controller */
353 if (pdev
->device
!= PCI_DEVICE_ID_EFFICEON
) {
354 printk(KERN_ERR PFX
"Unsupported Efficeon chipset (device id: %04x)\n",
359 printk(KERN_INFO PFX
"Detected Transmeta Efficeon TM8000 series chipset\n");
361 bridge
= agp_alloc_bridge();
365 bridge
->driver
= &efficeon_driver
;
367 bridge
->capndx
= cap_ptr
;
370 * The following fixes the case where the BIOS has "forgotten" to
371 * provide an address range for the GART.
372 * 20030610 - hamish@zot.org
374 r
= &pdev
->resource
[0];
375 if (!r
->start
&& r
->end
) {
376 if(pci_assign_resource(pdev
, 0)) {
377 printk(KERN_ERR PFX
"could not assign resource 0\n");
383 * If the device has not been properly setup, the following will catch
384 * the problem and should stop the system from crashing.
385 * 20030610 - hamish@zot.org
387 if (pci_enable_device(pdev
)) {
388 printk(KERN_ERR PFX
"Unable to Enable PCI device\n");
392 /* Fill in the mode register */
394 pci_read_config_dword(pdev
,
395 bridge
->capndx
+PCI_AGP_STATUS
,
399 pci_set_drvdata(pdev
, bridge
);
400 return agp_add_bridge(bridge
);
403 static void __devexit
agp_efficeon_remove(struct pci_dev
*pdev
)
405 struct agp_bridge_data
*bridge
= pci_get_drvdata(pdev
);
407 agp_remove_bridge(bridge
);
408 agp_put_bridge(bridge
);
411 static int agp_efficeon_suspend(struct pci_dev
*dev
, pm_message_t state
)
417 static struct pci_device_id agp_efficeon_pci_table
[] = {
419 .class = (PCI_CLASS_BRIDGE_HOST
<< 8),
421 .vendor
= PCI_VENDOR_ID_TRANSMETA
,
422 .device
= PCI_ANY_ID
,
423 .subvendor
= PCI_ANY_ID
,
424 .subdevice
= PCI_ANY_ID
,
429 MODULE_DEVICE_TABLE(pci
, agp_efficeon_pci_table
);
431 static struct pci_driver agp_efficeon_pci_driver
= {
432 .name
= "agpgart-efficeon",
433 .id_table
= agp_efficeon_pci_table
,
434 .probe
= agp_efficeon_probe
,
435 .remove
= agp_efficeon_remove
,
436 .suspend
= agp_efficeon_suspend
,
437 .resume
= agp_efficeon_resume
,
440 static int __init
agp_efficeon_init(void)
442 static int agp_initialised
=0;
447 if (agp_initialised
== 1)
451 return pci_register_driver(&agp_efficeon_pci_driver
);
454 static void __exit
agp_efficeon_cleanup(void)
456 pci_unregister_driver(&agp_efficeon_pci_driver
);
459 module_init(agp_efficeon_init
);
460 module_exit(agp_efficeon_cleanup
);
462 MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
463 MODULE_LICENSE("GPL and additional rights");