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 const struct gatt_mask efficeon_generic_masks
[] =
64 {.mask
= 0x00000001, .type
= 0}
67 /* This function does the same thing as mask_memory() for this chipset... */
68 static inline unsigned long efficeon_mask_memory(unsigned long addr
)
70 return addr
| 0x00000001;
73 static const struct aper_size_info_lvl2 efficeon_generic_sizes
[4] =
82 * Control interfaces are largely identical to
83 * the legacy Intel 440BX..
86 static int efficeon_fetch_size(void)
90 struct aper_size_info_lvl2
*values
;
92 pci_read_config_word(agp_bridge
->dev
, INTEL_APSIZE
, &temp
);
93 values
= A_SIZE_LVL2(agp_bridge
->driver
->aperture_sizes
);
95 for (i
= 0; i
< agp_bridge
->driver
->num_aperture_sizes
; i
++) {
96 if (temp
== values
[i
].size_value
) {
97 agp_bridge
->previous_size
=
98 agp_bridge
->current_size
= (void *) (values
+ i
);
99 agp_bridge
->aperture_size_idx
= i
;
100 return values
[i
].size
;
107 static void efficeon_tlbflush(struct agp_memory
* mem
)
109 printk(KERN_DEBUG PFX
"efficeon_tlbflush()\n");
110 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2200);
111 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
114 static void efficeon_cleanup(void)
117 struct aper_size_info_lvl2
*previous_size
;
119 printk(KERN_DEBUG PFX
"efficeon_cleanup()\n");
120 previous_size
= A_SIZE_LVL2(agp_bridge
->previous_size
);
121 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp
);
122 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, temp
& ~(1 << 9));
123 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
124 previous_size
->size_value
);
127 static int efficeon_configure(void)
131 struct aper_size_info_lvl2
*current_size
;
133 printk(KERN_DEBUG PFX
"efficeon_configure()\n");
135 current_size
= A_SIZE_LVL2(agp_bridge
->current_size
);
138 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
139 current_size
->size_value
);
141 /* address to map to */
142 pci_read_config_dword(agp_bridge
->dev
, AGP_APBASE
, &temp
);
143 agp_bridge
->gart_bus_addr
= (temp
& PCI_BASE_ADDRESS_MEM_MASK
);
146 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
149 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp2
);
150 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
,
151 (temp2
& ~(1 << 10)) | (1 << 9) | (1 << 11));
152 /* clear any possible error conditions */
153 pci_write_config_byte(agp_bridge
->dev
, INTEL_ERRSTS
+ 1, 7);
157 static int efficeon_free_gatt_table(struct agp_bridge_data
*bridge
)
159 int index
, freed
= 0;
161 for (index
= 0; index
< EFFICEON_L1_SIZE
; index
++) {
162 unsigned long page
= efficeon_private
.l1_table
[index
];
164 efficeon_private
.l1_table
[index
] = 0;
165 ClearPageReserved(virt_to_page((char *)page
));
169 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table(%p, %02x, %08x)\n",
170 agp_bridge
->dev
, EFFICEON_ATTPAGE
, index
);
171 pci_write_config_dword(agp_bridge
->dev
,
172 EFFICEON_ATTPAGE
, index
);
174 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table() freed %d pages\n", freed
);
180 * Since we don't need contiguous memory we just try
181 * to get the gatt table once
184 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
185 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
186 GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
187 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
189 #define GET_GATT(addr) (efficeon_private.gatt_pages[\
190 GET_PAGE_DIR_IDX(addr)]->remapped)
192 static int efficeon_create_gatt_table(struct agp_bridge_data
*bridge
)
195 const int pati
= EFFICEON_PATI
;
196 const int present
= EFFICEON_PRESENT
;
197 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
198 int num_entries
, l1_pages
;
200 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
202 printk(KERN_DEBUG PFX
"efficeon_create_gatt_table(%d)\n", num_entries
);
204 /* There are 2^10 PTE pages per PDE page */
205 BUG_ON(num_entries
& 0x3ff);
206 l1_pages
= num_entries
>> 10;
208 for (index
= 0 ; index
< l1_pages
; index
++) {
213 page
= efficeon_private
.l1_table
[index
];
216 page
= get_zeroed_page(GFP_KERNEL
);
218 efficeon_free_gatt_table(agp_bridge
);
221 SetPageReserved(virt_to_page((char *)page
));
223 for (offset
= 0; offset
< PAGE_SIZE
; offset
+= clflush_chunk
)
224 clflush((char *)page
+offset
);
226 efficeon_private
.l1_table
[index
] = page
;
228 value
= virt_to_gart((unsigned long *)page
) | pati
| present
| index
;
230 pci_write_config_dword(agp_bridge
->dev
,
231 EFFICEON_ATTPAGE
, value
);
237 static int efficeon_insert_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
239 int i
, count
= mem
->page_count
, num_entries
;
240 unsigned int *page
, *last_page
;
241 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
242 const unsigned long clflush_mask
= ~(clflush_chunk
-1);
244 printk(KERN_DEBUG PFX
"efficeon_insert_memory(%lx, %d)\n", pg_start
, count
);
246 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
247 if ((pg_start
+ mem
->page_count
) > num_entries
)
249 if (type
!= 0 || mem
->type
!= 0)
252 if (mem
->is_flushed
== FALSE
) {
253 global_cache_flush();
254 mem
->is_flushed
= TRUE
;
258 for (i
= 0; i
< count
; i
++) {
259 int index
= pg_start
+ i
;
260 unsigned long insert
= efficeon_mask_memory(mem
->memory
[i
]);
262 page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
267 page
+= (index
& 0x3ff);
270 /* clflush is slow, so don't clflush until we have to */
272 (((unsigned long)page
^(unsigned long)last_page
) &
282 agp_bridge
->driver
->tlb_flush(mem
);
286 static int efficeon_remove_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
288 int i
, count
= mem
->page_count
, num_entries
;
290 printk(KERN_DEBUG PFX
"efficeon_remove_memory(%lx, %d)\n", pg_start
, count
);
292 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
294 if ((pg_start
+ mem
->page_count
) > num_entries
)
296 if (type
!= 0 || mem
->type
!= 0)
299 for (i
= 0; i
< count
; i
++) {
300 int index
= pg_start
+ i
;
301 unsigned int *page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
305 page
+= (index
& 0x3ff);
308 agp_bridge
->driver
->tlb_flush(mem
);
313 static const struct agp_bridge_driver efficeon_driver
= {
314 .owner
= THIS_MODULE
,
315 .aperture_sizes
= efficeon_generic_sizes
,
316 .size_type
= LVL2_APER_SIZE
,
317 .num_aperture_sizes
= 4,
318 .configure
= efficeon_configure
,
319 .fetch_size
= efficeon_fetch_size
,
320 .cleanup
= efficeon_cleanup
,
321 .tlb_flush
= efficeon_tlbflush
,
322 .mask_memory
= agp_generic_mask_memory
,
323 .masks
= efficeon_generic_masks
,
324 .agp_enable
= agp_generic_enable
,
325 .cache_flush
= global_cache_flush
,
327 // Efficeon-specific GATT table setup / populate / teardown
328 .create_gatt_table
= efficeon_create_gatt_table
,
329 .free_gatt_table
= efficeon_free_gatt_table
,
330 .insert_memory
= efficeon_insert_memory
,
331 .remove_memory
= efficeon_remove_memory
,
332 .cant_use_aperture
= 0, // 1 might be faster?
335 .alloc_by_type
= agp_generic_alloc_by_type
,
336 .free_by_type
= agp_generic_free_by_type
,
337 .agp_alloc_page
= agp_generic_alloc_page
,
338 .agp_destroy_page
= agp_generic_destroy_page
,
339 .agp_type_to_mask_type
= agp_generic_type_to_mask_type
,
342 static int __devinit
agp_efficeon_probe(struct pci_dev
*pdev
,
343 const struct pci_device_id
*ent
)
345 struct agp_bridge_data
*bridge
;
349 cap_ptr
= pci_find_capability(pdev
, PCI_CAP_ID_AGP
);
353 /* Probe for Efficeon controller */
354 if (pdev
->device
!= PCI_DEVICE_ID_EFFICEON
) {
355 printk(KERN_ERR PFX
"Unsupported Efficeon chipset (device id: %04x)\n",
360 printk(KERN_INFO PFX
"Detected Transmeta Efficeon TM8000 series chipset\n");
362 bridge
= agp_alloc_bridge();
366 bridge
->driver
= &efficeon_driver
;
368 bridge
->capndx
= cap_ptr
;
371 * The following fixes the case where the BIOS has "forgotten" to
372 * provide an address range for the GART.
373 * 20030610 - hamish@zot.org
375 r
= &pdev
->resource
[0];
376 if (!r
->start
&& r
->end
) {
377 if (pci_assign_resource(pdev
, 0)) {
378 printk(KERN_ERR PFX
"could not assign resource 0\n");
379 agp_put_bridge(bridge
);
385 * If the device has not been properly setup, the following will catch
386 * the problem and should stop the system from crashing.
387 * 20030610 - hamish@zot.org
389 if (pci_enable_device(pdev
)) {
390 printk(KERN_ERR PFX
"Unable to Enable PCI device\n");
391 agp_put_bridge(bridge
);
395 /* Fill in the mode register */
397 pci_read_config_dword(pdev
,
398 bridge
->capndx
+PCI_AGP_STATUS
,
402 pci_set_drvdata(pdev
, bridge
);
403 return agp_add_bridge(bridge
);
406 static void __devexit
agp_efficeon_remove(struct pci_dev
*pdev
)
408 struct agp_bridge_data
*bridge
= pci_get_drvdata(pdev
);
410 agp_remove_bridge(bridge
);
411 agp_put_bridge(bridge
);
415 static int agp_efficeon_suspend(struct pci_dev
*dev
, pm_message_t state
)
420 static int agp_efficeon_resume(struct pci_dev
*pdev
)
422 printk(KERN_DEBUG PFX
"agp_efficeon_resume()\n");
423 return efficeon_configure();
427 static struct pci_device_id agp_efficeon_pci_table
[] = {
429 .class = (PCI_CLASS_BRIDGE_HOST
<< 8),
431 .vendor
= PCI_VENDOR_ID_TRANSMETA
,
432 .device
= PCI_ANY_ID
,
433 .subvendor
= PCI_ANY_ID
,
434 .subdevice
= PCI_ANY_ID
,
439 MODULE_DEVICE_TABLE(pci
, agp_efficeon_pci_table
);
441 static struct pci_driver agp_efficeon_pci_driver
= {
442 .name
= "agpgart-efficeon",
443 .id_table
= agp_efficeon_pci_table
,
444 .probe
= agp_efficeon_probe
,
445 .remove
= agp_efficeon_remove
,
447 .suspend
= agp_efficeon_suspend
,
448 .resume
= agp_efficeon_resume
,
452 static int __init
agp_efficeon_init(void)
454 static int agp_initialised
=0;
459 if (agp_initialised
== 1)
463 return pci_register_driver(&agp_efficeon_pci_driver
);
466 static void __exit
agp_efficeon_cleanup(void)
468 pci_unregister_driver(&agp_efficeon_pci_driver
);
471 module_init(agp_efficeon_init
);
472 module_exit(agp_efficeon_cleanup
);
474 MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
475 MODULE_LICENSE("GPL and additional rights");