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)
133 struct aper_size_info_lvl2
*current_size
;
135 printk(KERN_DEBUG PFX
"efficeon_configure()\n");
137 current_size
= A_SIZE_LVL2(agp_bridge
->current_size
);
140 pci_write_config_word(agp_bridge
->dev
, INTEL_APSIZE
,
141 current_size
->size_value
);
143 /* address to map to */
144 pci_read_config_dword(agp_bridge
->dev
, AGP_APBASE
, &temp
);
145 agp_bridge
->gart_bus_addr
= (temp
& PCI_BASE_ADDRESS_MEM_MASK
);
148 pci_write_config_dword(agp_bridge
->dev
, INTEL_AGPCTRL
, 0x2280);
151 pci_read_config_word(agp_bridge
->dev
, INTEL_NBXCFG
, &temp2
);
152 pci_write_config_word(agp_bridge
->dev
, INTEL_NBXCFG
,
153 (temp2
& ~(1 << 10)) | (1 << 9) | (1 << 11));
154 /* clear any possible error conditions */
155 pci_write_config_byte(agp_bridge
->dev
, INTEL_ERRSTS
+ 1, 7);
159 static int efficeon_free_gatt_table(struct agp_bridge_data
*bridge
)
161 int index
, freed
= 0;
163 for (index
= 0; index
< EFFICEON_L1_SIZE
; index
++) {
164 unsigned long page
= efficeon_private
.l1_table
[index
];
166 efficeon_private
.l1_table
[index
] = 0;
167 ClearPageReserved(virt_to_page((char *)page
));
171 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table(%p, %02x, %08x)\n",
172 agp_bridge
->dev
, EFFICEON_ATTPAGE
, index
);
173 pci_write_config_dword(agp_bridge
->dev
,
174 EFFICEON_ATTPAGE
, index
);
176 printk(KERN_DEBUG PFX
"efficeon_free_gatt_table() freed %d pages\n", freed
);
182 * Since we don't need contiguous memory we just try
183 * to get the gatt table once
186 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
187 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
188 GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
189 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
191 #define GET_GATT(addr) (efficeon_private.gatt_pages[\
192 GET_PAGE_DIR_IDX(addr)]->remapped)
194 static int efficeon_create_gatt_table(struct agp_bridge_data
*bridge
)
197 const int pati
= EFFICEON_PATI
;
198 const int present
= EFFICEON_PRESENT
;
199 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
200 int num_entries
, l1_pages
;
202 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
204 printk(KERN_DEBUG PFX
"efficeon_create_gatt_table(%d)\n", num_entries
);
206 /* There are 2^10 PTE pages per PDE page */
207 BUG_ON(num_entries
& 0x3ff);
208 l1_pages
= num_entries
>> 10;
210 for (index
= 0 ; index
< l1_pages
; index
++) {
215 page
= efficeon_private
.l1_table
[index
];
218 page
= get_zeroed_page(GFP_KERNEL
);
220 efficeon_free_gatt_table(agp_bridge
);
223 SetPageReserved(virt_to_page((char *)page
));
225 for (offset
= 0; offset
< PAGE_SIZE
; offset
+= clflush_chunk
)
226 clflush((char *)page
+offset
);
228 efficeon_private
.l1_table
[index
] = page
;
230 value
= virt_to_phys((unsigned long *)page
) | pati
| present
| index
;
232 pci_write_config_dword(agp_bridge
->dev
,
233 EFFICEON_ATTPAGE
, value
);
239 static int efficeon_insert_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
241 int i
, count
= mem
->page_count
, num_entries
;
242 unsigned int *page
, *last_page
;
243 const int clflush_chunk
= ((cpuid_ebx(1) >> 8) & 0xff) << 3;
244 const unsigned long clflush_mask
= ~(clflush_chunk
-1);
246 printk(KERN_DEBUG PFX
"efficeon_insert_memory(%lx, %d)\n", pg_start
, count
);
248 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
249 if ((pg_start
+ mem
->page_count
) > num_entries
)
251 if (type
!= 0 || mem
->type
!= 0)
254 if (!mem
->is_flushed
) {
255 global_cache_flush();
256 mem
->is_flushed
= true;
260 for (i
= 0; i
< count
; i
++) {
261 int index
= pg_start
+ i
;
262 unsigned long insert
= efficeon_mask_memory(mem
->pages
[i
]);
264 page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
269 page
+= (index
& 0x3ff);
272 /* clflush is slow, so don't clflush until we have to */
274 (((unsigned long)page
^(unsigned long)last_page
) &
284 agp_bridge
->driver
->tlb_flush(mem
);
288 static int efficeon_remove_memory(struct agp_memory
* mem
, off_t pg_start
, int type
)
290 int i
, count
= mem
->page_count
, num_entries
;
292 printk(KERN_DEBUG PFX
"efficeon_remove_memory(%lx, %d)\n", pg_start
, count
);
294 num_entries
= A_SIZE_LVL2(agp_bridge
->current_size
)->num_entries
;
296 if ((pg_start
+ mem
->page_count
) > num_entries
)
298 if (type
!= 0 || mem
->type
!= 0)
301 for (i
= 0; i
< count
; i
++) {
302 int index
= pg_start
+ i
;
303 unsigned int *page
= (unsigned int *) efficeon_private
.l1_table
[index
>> 10];
307 page
+= (index
& 0x3ff);
310 agp_bridge
->driver
->tlb_flush(mem
);
315 static const struct agp_bridge_driver efficeon_driver
= {
316 .owner
= THIS_MODULE
,
317 .aperture_sizes
= efficeon_generic_sizes
,
318 .size_type
= LVL2_APER_SIZE
,
319 .num_aperture_sizes
= 4,
320 .configure
= efficeon_configure
,
321 .fetch_size
= efficeon_fetch_size
,
322 .cleanup
= efficeon_cleanup
,
323 .tlb_flush
= efficeon_tlbflush
,
324 .mask_memory
= agp_generic_mask_memory
,
325 .masks
= efficeon_generic_masks
,
326 .agp_enable
= agp_generic_enable
,
327 .cache_flush
= global_cache_flush
,
329 // Efficeon-specific GATT table setup / populate / teardown
330 .create_gatt_table
= efficeon_create_gatt_table
,
331 .free_gatt_table
= efficeon_free_gatt_table
,
332 .insert_memory
= efficeon_insert_memory
,
333 .remove_memory
= efficeon_remove_memory
,
334 .cant_use_aperture
= false, // true might be faster?
337 .alloc_by_type
= agp_generic_alloc_by_type
,
338 .free_by_type
= agp_generic_free_by_type
,
339 .agp_alloc_page
= agp_generic_alloc_page
,
340 .agp_alloc_pages
= agp_generic_alloc_pages
,
341 .agp_destroy_page
= agp_generic_destroy_page
,
342 .agp_destroy_pages
= agp_generic_destroy_pages
,
343 .agp_type_to_mask_type
= agp_generic_type_to_mask_type
,
346 static int agp_efficeon_probe(struct pci_dev
*pdev
,
347 const struct pci_device_id
*ent
)
349 struct agp_bridge_data
*bridge
;
353 cap_ptr
= pci_find_capability(pdev
, PCI_CAP_ID_AGP
);
357 /* Probe for Efficeon controller */
358 if (pdev
->device
!= PCI_DEVICE_ID_EFFICEON
) {
359 printk(KERN_ERR PFX
"Unsupported Efficeon chipset (device id: %04x)\n",
364 printk(KERN_INFO PFX
"Detected Transmeta Efficeon TM8000 series chipset\n");
366 bridge
= agp_alloc_bridge();
370 bridge
->driver
= &efficeon_driver
;
372 bridge
->capndx
= cap_ptr
;
375 * If the device has not been properly setup, the following will catch
376 * the problem and should stop the system from crashing.
377 * 20030610 - hamish@zot.org
379 if (pci_enable_device(pdev
)) {
380 printk(KERN_ERR PFX
"Unable to Enable PCI device\n");
381 agp_put_bridge(bridge
);
386 * The following fixes the case where the BIOS has "forgotten" to
387 * provide an address range for the GART.
388 * 20030610 - hamish@zot.org
390 r
= &pdev
->resource
[0];
391 if (!r
->start
&& r
->end
) {
392 if (pci_assign_resource(pdev
, 0)) {
393 printk(KERN_ERR PFX
"could not assign resource 0\n");
394 agp_put_bridge(bridge
);
399 /* Fill in the mode register */
401 pci_read_config_dword(pdev
,
402 bridge
->capndx
+PCI_AGP_STATUS
,
406 pci_set_drvdata(pdev
, bridge
);
407 return agp_add_bridge(bridge
);
410 static void agp_efficeon_remove(struct pci_dev
*pdev
)
412 struct agp_bridge_data
*bridge
= pci_get_drvdata(pdev
);
414 agp_remove_bridge(bridge
);
415 agp_put_bridge(bridge
);
419 static int agp_efficeon_suspend(struct pci_dev
*dev
, pm_message_t state
)
424 static int agp_efficeon_resume(struct pci_dev
*pdev
)
426 printk(KERN_DEBUG PFX
"agp_efficeon_resume()\n");
427 return efficeon_configure();
431 static struct pci_device_id agp_efficeon_pci_table
[] = {
433 .class = (PCI_CLASS_BRIDGE_HOST
<< 8),
435 .vendor
= PCI_VENDOR_ID_TRANSMETA
,
436 .device
= PCI_ANY_ID
,
437 .subvendor
= PCI_ANY_ID
,
438 .subdevice
= PCI_ANY_ID
,
443 MODULE_DEVICE_TABLE(pci
, agp_efficeon_pci_table
);
445 static struct pci_driver agp_efficeon_pci_driver
= {
446 .name
= "agpgart-efficeon",
447 .id_table
= agp_efficeon_pci_table
,
448 .probe
= agp_efficeon_probe
,
449 .remove
= agp_efficeon_remove
,
451 .suspend
= agp_efficeon_suspend
,
452 .resume
= agp_efficeon_resume
,
456 static int __init
agp_efficeon_init(void)
458 static int agp_initialised
=0;
463 if (agp_initialised
== 1)
467 return pci_register_driver(&agp_efficeon_pci_driver
);
470 static void __exit
agp_efficeon_cleanup(void)
472 pci_unregister_driver(&agp_efficeon_pci_driver
);
475 module_init(agp_efficeon_init
);
476 module_exit(agp_efficeon_cleanup
);
478 MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
479 MODULE_LICENSE("GPL and additional rights");