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>
31 #include "intel-agp.h"
34 * The real differences to the generic AGP code is
35 * in the GART mappings - a two-level setup with the
36 * first level being an on-chip 64-entry table.
38 * The page array is filled through the ATTPAGE register
39 * (Aperture Translation Table Page Register) at 0xB8. Bits:
40 * 31:20: physical page address
41 * 11:9: Page Attribute Table Index (PATI)
42 * must match the PAT index for the
43 * mapped pages (the 2nd level page table pages
44 * themselves should be just regular WB-cacheable,
45 * so this is normally zero.)
47 * 7:6: reserved, write as zero
48 * 5:0: GATT directory index: which 1st-level entry
50 * The Efficeon AGP spec requires pages to be WB-cacheable
51 * but to be explicitly CLFLUSH'd after any changes.
53 #define EFFICEON_ATTPAGE 0xb8
54 #define EFFICEON_L1_SIZE 64 /* Number of PDE pages */
56 #define EFFICEON_PATI (0 << 9)
57 #define EFFICEON_PRESENT (1 << 8)
59 static struct _efficeon_private
{
60 unsigned long l1_table
[EFFICEON_L1_SIZE
];
63 static const struct gatt_mask efficeon_generic_masks
[] =
65 {.mask
= 0x00000001, .type
= 0}
68 /* This function does the same thing as mask_memory() for this chipset... */
69 static inline unsigned long efficeon_mask_memory(struct page
*page
)
71 unsigned long addr
= page_to_phys(page
);
72 return addr
| 0x00000001;
75 static const struct aper_size_info_lvl2 efficeon_generic_sizes
[4] =
84 * Control interfaces are largely identical to
85 * the legacy Intel 440BX..
88 static int efficeon_fetch_size(void)
92 struct aper_size_info_lvl2
*values
;
94 pci_read_config_word(agp_bridge
->dev
, INTEL_APSIZE
, &temp
);
95 values
= A_SIZE_LVL2(agp_bridge
->driver
->aperture_sizes
);
97 for (i
= 0; i
< agp_bridge
->driver
->num_aperture_sizes
; i
++) {
98 if (temp
== values
[i
].size_value
) {
99 agp_bridge
->previous_size
=
100 agp_bridge
->current_size
= (void *) (values
+ i
);
101 agp_bridge
->aperture_size_idx
= i
;
102 return values
[i
].size
;
109 static void efficeon_tlbflush(struct agp_memory
* mem
)
111 printk(KERN_DEBUG PFX
"efficeon_tlbflush()\n");
112 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2200);
113 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
116 static void efficeon_cleanup(void)
119 struct aper_size_info_lvl2
*previous_size
;
121 printk(KERN_DEBUG PFX
"efficeon_cleanup()\n");
122 previous_size
= A_SIZE_LVL2(agp_bridge
->previous_size
);
123 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp
);
124 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, temp
& ~(1 << 9));
125 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
126 previous_size
->size_value
);
129 static int efficeon_configure(void)
132 struct aper_size_info_lvl2
*current_size
;
134 printk(KERN_DEBUG PFX
"efficeon_configure()\n");
136 current_size
= A_SIZE_LVL2(agp_bridge
->current_size
);
139 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
140 current_size
->size_value
);
142 /* address to map to */
143 agp_bridge
->gart_bus_addr
= pci_bus_address(agp_bridge
->dev
,
147 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
150 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp2
);
151 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
,
152 (temp2
& ~(1 << 10)) | (1 << 9) | (1 << 11));
153 /* clear any possible error conditions */
154 pci_write_config_byte(agp_bridge
->dev
, INTEL_ERRSTS
+ 1, 7);
158 static int efficeon_free_gatt_table(struct agp_bridge_data
*bridge
)
160 int index
, freed
= 0;
162 for (index
= 0; index
< EFFICEON_L1_SIZE
; index
++) {
163 unsigned long page
= efficeon_private
.l1_table
[index
];
165 efficeon_private
.l1_table
[index
] = 0;
166 ClearPageReserved(virt_to_page((char *)page
));
170 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table(%p, %02x, %08x)\n",
171 agp_bridge
->dev
, EFFICEON_ATTPAGE
, index
);
172 pci_write_config_dword(agp_bridge
->dev
,
173 EFFICEON_ATTPAGE
, index
);
175 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table() freed %d pages\n", freed
);
181 * Since we don't need contiguous memory we just try
182 * to get the gatt table once
185 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
186 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
187 GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
188 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
190 #define GET_GATT(addr) (efficeon_private.gatt_pages[\
191 GET_PAGE_DIR_IDX(addr)]->remapped)
193 static int efficeon_create_gatt_table(struct agp_bridge_data
*bridge
)
196 const int pati
= EFFICEON_PATI
;
197 const int present
= EFFICEON_PRESENT
;
198 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
199 int num_entries
, l1_pages
;
201 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
203 printk(KERN_DEBUG PFX
"efficeon_create_gatt_table(%d)\n", num_entries
);
205 /* There are 2^10 PTE pages per PDE page */
206 BUG_ON(num_entries
& 0x3ff);
207 l1_pages
= num_entries
>> 10;
209 for (index
= 0 ; index
< l1_pages
; index
++) {
214 page
= efficeon_private
.l1_table
[index
];
217 page
= get_zeroed_page(GFP_KERNEL
);
219 efficeon_free_gatt_table(agp_bridge
);
222 SetPageReserved(virt_to_page((char *)page
));
224 for (offset
= 0; offset
< PAGE_SIZE
; offset
+= clflush_chunk
)
225 clflush((char *)page
+offset
);
227 efficeon_private
.l1_table
[index
] = page
;
229 value
= virt_to_phys((unsigned long *)page
) | pati
| present
| index
;
231 pci_write_config_dword(agp_bridge
->dev
,
232 EFFICEON_ATTPAGE
, value
);
238 static int efficeon_insert_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
240 int i
, count
= mem
->page_count
, num_entries
;
241 unsigned int *page
, *last_page
;
242 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
243 const unsigned long clflush_mask
= ~(clflush_chunk
-1);
245 printk(KERN_DEBUG PFX
"efficeon_insert_memory(%lx, %d)\n", pg_start
, count
);
247 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
248 if ((pg_start
+ mem
->page_count
) > num_entries
)
250 if (type
!= 0 || mem
->type
!= 0)
253 if (!mem
->is_flushed
) {
254 global_cache_flush();
255 mem
->is_flushed
= true;
259 for (i
= 0; i
< count
; i
++) {
260 int index
= pg_start
+ i
;
261 unsigned long insert
= efficeon_mask_memory(mem
->pages
[i
]);
263 page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
268 page
+= (index
& 0x3ff);
271 /* clflush is slow, so don't clflush until we have to */
273 (((unsigned long)page
^(unsigned long)last_page
) &
283 agp_bridge
->driver
->tlb_flush(mem
);
287 static int efficeon_remove_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
289 int i
, count
= mem
->page_count
, num_entries
;
291 printk(KERN_DEBUG PFX
"efficeon_remove_memory(%lx, %d)\n", pg_start
, count
);
293 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
295 if ((pg_start
+ mem
->page_count
) > num_entries
)
297 if (type
!= 0 || mem
->type
!= 0)
300 for (i
= 0; i
< count
; i
++) {
301 int index
= pg_start
+ i
;
302 unsigned int *page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
306 page
+= (index
& 0x3ff);
309 agp_bridge
->driver
->tlb_flush(mem
);
314 static const struct agp_bridge_driver efficeon_driver
= {
315 .owner
= THIS_MODULE
,
316 .aperture_sizes
= efficeon_generic_sizes
,
317 .size_type
= LVL2_APER_SIZE
,
318 .num_aperture_sizes
= 4,
319 .configure
= efficeon_configure
,
320 .fetch_size
= efficeon_fetch_size
,
321 .cleanup
= efficeon_cleanup
,
322 .tlb_flush
= efficeon_tlbflush
,
323 .mask_memory
= agp_generic_mask_memory
,
324 .masks
= efficeon_generic_masks
,
325 .agp_enable
= agp_generic_enable
,
326 .cache_flush
= global_cache_flush
,
328 // Efficeon-specific GATT table setup / populate / teardown
329 .create_gatt_table
= efficeon_create_gatt_table
,
330 .free_gatt_table
= efficeon_free_gatt_table
,
331 .insert_memory
= efficeon_insert_memory
,
332 .remove_memory
= efficeon_remove_memory
,
333 .cant_use_aperture
= false, // true might be faster?
336 .alloc_by_type
= agp_generic_alloc_by_type
,
337 .free_by_type
= agp_generic_free_by_type
,
338 .agp_alloc_page
= agp_generic_alloc_page
,
339 .agp_alloc_pages
= agp_generic_alloc_pages
,
340 .agp_destroy_page
= agp_generic_destroy_page
,
341 .agp_destroy_pages
= agp_generic_destroy_pages
,
342 .agp_type_to_mask_type
= agp_generic_type_to_mask_type
,
345 static int agp_efficeon_probe(struct pci_dev
*pdev
,
346 const struct pci_device_id
*ent
)
348 struct agp_bridge_data
*bridge
;
352 cap_ptr
= pci_find_capability(pdev
, PCI_CAP_ID_AGP
);
356 /* Probe for Efficeon controller */
357 if (pdev
->device
!= PCI_DEVICE_ID_EFFICEON
) {
358 printk(KERN_ERR PFX
"Unsupported Efficeon chipset (device id: %04x)\n",
363 printk(KERN_INFO PFX
"Detected Transmeta Efficeon TM8000 series chipset\n");
365 bridge
= agp_alloc_bridge();
369 bridge
->driver
= &efficeon_driver
;
371 bridge
->capndx
= cap_ptr
;
374 * If the device has not been properly setup, the following will catch
375 * the problem and should stop the system from crashing.
376 * 20030610 - hamish@zot.org
378 if (pci_enable_device(pdev
)) {
379 printk(KERN_ERR PFX
"Unable to Enable PCI device\n");
380 agp_put_bridge(bridge
);
385 * The following fixes the case where the BIOS has "forgotten" to
386 * provide an address range for the GART.
387 * 20030610 - hamish@zot.org
389 r
= &pdev
->resource
[0];
390 if (!r
->start
&& r
->end
) {
391 if (pci_assign_resource(pdev
, 0)) {
392 printk(KERN_ERR PFX
"could not assign resource 0\n");
393 agp_put_bridge(bridge
);
398 /* Fill in the mode register */
400 pci_read_config_dword(pdev
,
401 bridge
->capndx
+PCI_AGP_STATUS
,
405 pci_set_drvdata(pdev
, bridge
);
406 return agp_add_bridge(bridge
);
409 static void agp_efficeon_remove(struct pci_dev
*pdev
)
411 struct agp_bridge_data
*bridge
= pci_get_drvdata(pdev
);
413 agp_remove_bridge(bridge
);
414 agp_put_bridge(bridge
);
418 static int agp_efficeon_suspend(struct pci_dev
*dev
, pm_message_t state
)
423 static int agp_efficeon_resume(struct pci_dev
*pdev
)
425 printk(KERN_DEBUG PFX
"agp_efficeon_resume()\n");
426 return efficeon_configure();
430 static const struct pci_device_id agp_efficeon_pci_table
[] = {
432 .class = (PCI_CLASS_BRIDGE_HOST
<< 8),
434 .vendor
= PCI_VENDOR_ID_TRANSMETA
,
435 .device
= PCI_ANY_ID
,
436 .subvendor
= PCI_ANY_ID
,
437 .subdevice
= PCI_ANY_ID
,
442 MODULE_DEVICE_TABLE(pci
, agp_efficeon_pci_table
);
444 static struct pci_driver agp_efficeon_pci_driver
= {
445 .name
= "agpgart-efficeon",
446 .id_table
= agp_efficeon_pci_table
,
447 .probe
= agp_efficeon_probe
,
448 .remove
= agp_efficeon_remove
,
450 .suspend
= agp_efficeon_suspend
,
451 .resume
= agp_efficeon_resume
,
455 static int __init
agp_efficeon_init(void)
457 static int agp_initialised
=0;
462 if (agp_initialised
== 1)
466 return pci_register_driver(&agp_efficeon_pci_driver
);
469 static void __exit
agp_efficeon_cleanup(void)
471 pci_unregister_driver(&agp_efficeon_pci_driver
);
474 module_init(agp_efficeon_init
);
475 module_exit(agp_efficeon_cleanup
);
477 MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
478 MODULE_LICENSE("GPL and additional rights");