Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
efficeon-agp.c
Go to the documentation of this file.
1 /*
2  * Transmeta's Efficeon AGPGART driver.
3  *
4  * Based upon a diff by Linus around November '02.
5  *
6  * Ported to the 2.6 kernel by Carlos Puchol <[email protected]>
7  * and H. Peter Anvin <[email protected]>.
8  */
9 
10 /*
11  * NOTE-cpg-040217:
12  *
13  * - when compiled as a module, after loading the module,
14  * it will refuse to unload, indicating it is in use,
15  * when it is not.
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)
21  */
22 
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>
29 #include <linux/mm.h>
30 #include "agp.h"
31 #include "intel-agp.h"
32 
33 /*
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.
37  *
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.)
46  * 8: Present
47  * 7:6: reserved, write as zero
48  * 5:0: GATT directory index: which 1st-level entry
49  *
50  * The Efficeon AGP spec requires pages to be WB-cacheable
51  * but to be explicitly CLFLUSH'd after any changes.
52  */
53 #define EFFICEON_ATTPAGE 0xb8
54 #define EFFICEON_L1_SIZE 64 /* Number of PDE pages */
55 
56 #define EFFICEON_PATI (0 << 9)
57 #define EFFICEON_PRESENT (1 << 8)
58 
59 static struct _efficeon_private {
60  unsigned long l1_table[EFFICEON_L1_SIZE];
61 } efficeon_private;
62 
63 static const struct gatt_mask efficeon_generic_masks[] =
64 {
65  {.mask = 0x00000001, .type = 0}
66 };
67 
68 /* This function does the same thing as mask_memory() for this chipset... */
69 static inline unsigned long efficeon_mask_memory(struct page *page)
70 {
71  unsigned long addr = page_to_phys(page);
72  return addr | 0x00000001;
73 }
74 
75 static const struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
76 {
77  {256, 65536, 0},
78  {128, 32768, 32},
79  {64, 16384, 48},
80  {32, 8192, 56}
81 };
82 
83 /*
84  * Control interfaces are largely identical to
85  * the legacy Intel 440BX..
86  */
87 
88 static int efficeon_fetch_size(void)
89 {
90  int i;
91  u16 temp;
93 
94  pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
95  values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
96 
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;
103  }
104  }
105 
106  return 0;
107 }
108 
109 static void efficeon_tlbflush(struct agp_memory * mem)
110 {
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);
114 }
115 
116 static void efficeon_cleanup(void)
117 {
118  u16 temp;
119  struct aper_size_info_lvl2 *previous_size;
120 
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);
127 }
128 
129 static int efficeon_configure(void)
130 {
131  u32 temp;
132  u16 temp2;
133  struct aper_size_info_lvl2 *current_size;
134 
135  printk(KERN_DEBUG PFX "efficeon_configure()\n");
136 
137  current_size = A_SIZE_LVL2(agp_bridge->current_size);
138 
139  /* aperture size */
140  pci_write_config_word(agp_bridge->dev, INTEL_APSIZE,
141  current_size->size_value);
142 
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);
146 
147  /* agpctrl */
148  pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
149 
150  /* paccfg/nbxcfg */
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);
156  return 0;
157 }
158 
159 static int efficeon_free_gatt_table(struct agp_bridge_data *bridge)
160 {
161  int index, freed = 0;
162 
163  for (index = 0; index < EFFICEON_L1_SIZE; index++) {
164  unsigned long page = efficeon_private.l1_table[index];
165  if (page) {
166  efficeon_private.l1_table[index] = 0;
167  ClearPageReserved(virt_to_page((char *)page));
168  free_page(page);
169  freed++;
170  }
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);
175  }
176  printk(KERN_DEBUG PFX "efficeon_free_gatt_table() freed %d pages\n", freed);
177  return 0;
178 }
179 
180 
181 /*
182  * Since we don't need contiguous memory we just try
183  * to get the gatt table once
184  */
185 
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)
190 #undef GET_GATT
191 #define GET_GATT(addr) (efficeon_private.gatt_pages[\
192  GET_PAGE_DIR_IDX(addr)]->remapped)
193 
194 static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
195 {
196  int index;
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;
201 
202  num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
203 
204  printk(KERN_DEBUG PFX "efficeon_create_gatt_table(%d)\n", num_entries);
205 
206  /* There are 2^10 PTE pages per PDE page */
207  BUG_ON(num_entries & 0x3ff);
208  l1_pages = num_entries >> 10;
209 
210  for (index = 0 ; index < l1_pages ; index++) {
211  int offset;
212  unsigned long page;
213  unsigned long value;
214 
215  page = efficeon_private.l1_table[index];
216  BUG_ON(page);
217 
218  page = get_zeroed_page(GFP_KERNEL);
219  if (!page) {
220  efficeon_free_gatt_table(agp_bridge);
221  return -ENOMEM;
222  }
223  SetPageReserved(virt_to_page((char *)page));
224 
225  for (offset = 0; offset < PAGE_SIZE; offset += clflush_chunk)
226  clflush((char *)page+offset);
227 
228  efficeon_private.l1_table[index] = page;
229 
230  value = virt_to_phys((unsigned long *)page) | pati | present | index;
231 
232  pci_write_config_dword(agp_bridge->dev,
233  EFFICEON_ATTPAGE, value);
234  }
235 
236  return 0;
237 }
238 
239 static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
240 {
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);
245 
246  printk(KERN_DEBUG PFX "efficeon_insert_memory(%lx, %d)\n", pg_start, count);
247 
248  num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
249  if ((pg_start + mem->page_count) > num_entries)
250  return -EINVAL;
251  if (type != 0 || mem->type != 0)
252  return -EINVAL;
253 
254  if (!mem->is_flushed) {
256  mem->is_flushed = true;
257  }
258 
259  last_page = NULL;
260  for (i = 0; i < count; i++) {
261  int index = pg_start + i;
262  unsigned long insert = efficeon_mask_memory(mem->pages[i]);
263 
264  page = (unsigned int *) efficeon_private.l1_table[index >> 10];
265 
266  if (!page)
267  continue;
268 
269  page += (index & 0x3ff);
270  *page = insert;
271 
272  /* clflush is slow, so don't clflush until we have to */
273  if (last_page &&
274  (((unsigned long)page^(unsigned long)last_page) &
275  clflush_mask))
276  clflush(last_page);
277 
278  last_page = page;
279  }
280 
281  if ( last_page )
282  clflush(last_page);
283 
284  agp_bridge->driver->tlb_flush(mem);
285  return 0;
286 }
287 
288 static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int type)
289 {
290  int i, count = mem->page_count, num_entries;
291 
292  printk(KERN_DEBUG PFX "efficeon_remove_memory(%lx, %d)\n", pg_start, count);
293 
294  num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
295 
296  if ((pg_start + mem->page_count) > num_entries)
297  return -EINVAL;
298  if (type != 0 || mem->type != 0)
299  return -EINVAL;
300 
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];
304 
305  if (!page)
306  continue;
307  page += (index & 0x3ff);
308  *page = 0;
309  }
310  agp_bridge->driver->tlb_flush(mem);
311  return 0;
312 }
313 
314 
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,
328 
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?
335 
336  // Generic
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,
344 };
345 
346 static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
347  const struct pci_device_id *ent)
348 {
349  struct agp_bridge_data *bridge;
350  u8 cap_ptr;
351  struct resource *r;
352 
353  cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
354  if (!cap_ptr)
355  return -ENODEV;
356 
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",
360  pdev->device);
361  return -ENODEV;
362  }
363 
364  printk(KERN_INFO PFX "Detected Transmeta Efficeon TM8000 series chipset\n");
365 
366  bridge = agp_alloc_bridge();
367  if (!bridge)
368  return -ENOMEM;
369 
370  bridge->driver = &efficeon_driver;
371  bridge->dev = pdev;
372  bridge->capndx = cap_ptr;
373 
374  /*
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 - [email protected]
378  */
379  if (pci_enable_device(pdev)) {
380  printk(KERN_ERR PFX "Unable to Enable PCI device\n");
381  agp_put_bridge(bridge);
382  return -ENODEV;
383  }
384 
385  /*
386  * The following fixes the case where the BIOS has "forgotten" to
387  * provide an address range for the GART.
388  * 20030610 - [email protected]
389  */
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);
395  return -ENODEV;
396  }
397  }
398 
399  /* Fill in the mode register */
400  if (cap_ptr) {
401  pci_read_config_dword(pdev,
402  bridge->capndx+PCI_AGP_STATUS,
403  &bridge->mode);
404  }
405 
406  pci_set_drvdata(pdev, bridge);
407  return agp_add_bridge(bridge);
408 }
409 
410 static void __devexit agp_efficeon_remove(struct pci_dev *pdev)
411 {
412  struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
413 
414  agp_remove_bridge(bridge);
415  agp_put_bridge(bridge);
416 }
417 
418 #ifdef CONFIG_PM
419 static int agp_efficeon_suspend(struct pci_dev *dev, pm_message_t state)
420 {
421  return 0;
422 }
423 
424 static int agp_efficeon_resume(struct pci_dev *pdev)
425 {
426  printk(KERN_DEBUG PFX "agp_efficeon_resume()\n");
427  return efficeon_configure();
428 }
429 #endif
430 
431 static struct pci_device_id agp_efficeon_pci_table[] = {
432  {
433  .class = (PCI_CLASS_BRIDGE_HOST << 8),
434  .class_mask = ~0,
436  .device = PCI_ANY_ID,
439  },
440  { }
441 };
442 
443 MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);
444 
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,
450 #ifdef CONFIG_PM
451  .suspend = agp_efficeon_suspend,
452  .resume = agp_efficeon_resume,
453 #endif
454 };
455 
456 static int __init agp_efficeon_init(void)
457 {
458  static int agp_initialised=0;
459 
460  if (agp_off)
461  return -EINVAL;
462 
463  if (agp_initialised == 1)
464  return 0;
465  agp_initialised=1;
466 
467  return pci_register_driver(&agp_efficeon_pci_driver);
468 }
469 
470 static void __exit agp_efficeon_cleanup(void)
471 {
472  pci_unregister_driver(&agp_efficeon_pci_driver);
473 }
474 
475 module_init(agp_efficeon_init);
476 module_exit(agp_efficeon_cleanup);
477 
478 MODULE_AUTHOR("Carlos Puchol <[email protected]>");
479 MODULE_LICENSE("GPL and additional rights");