ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / agp / hp-agp.c
1 /*
2  * HP AGPGART routines.
3  *      Copyright (C) 2002-2003 Hewlett-Packard Co
4  *              Bjorn Helgaas <bjorn_helgaas@hp.com>
5  */
6
7 #include <linux/acpi.h>
8 #include <linux/module.h>
9 #include <linux/pci.h>
10 #include <linux/init.h>
11 #include <linux/agp_backend.h>
12
13 #include <asm/acpi-ext.h>
14
15 #include "agp.h"
16
17 #ifndef log2
18 #define log2(x)         ffz(~(x))
19 #endif
20
21 #define HP_ZX1_IOC_OFFSET       0x1000  /* ACPI reports SBA, we want IOC */
22
23 /* HP ZX1 IOC registers */
24 #define HP_ZX1_IBASE            0x300
25 #define HP_ZX1_IMASK            0x308
26 #define HP_ZX1_PCOM             0x310
27 #define HP_ZX1_TCNFG            0x318
28 #define HP_ZX1_PDIR_BASE        0x320
29
30 #define HP_ZX1_IOVA_BASE        GB(1UL)
31 #define HP_ZX1_IOVA_SIZE        GB(1UL)
32 #define HP_ZX1_GART_SIZE        (HP_ZX1_IOVA_SIZE / 2)
33 #define HP_ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
34
35 #define HP_ZX1_PDIR_VALID_BIT   0x8000000000000000UL
36 #define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> hp_private.io_tlb_shift)
37
38 #define AGP8X_MODE_BIT          3
39 #define AGP8X_MODE              (1 << AGP8X_MODE_BIT)
40
41 /* AGP bridge need not be PCI device, but DRM thinks it is. */
42 static struct pci_dev fake_bridge_dev;
43
44 static int hp_zx1_gart_found;
45
46 static struct aper_size_info_fixed hp_zx1_sizes[] =
47 {
48         {0, 0, 0},              /* filled in by hp_zx1_fetch_size() */
49 };
50
51 static struct gatt_mask hp_zx1_masks[] =
52 {
53         {.mask = HP_ZX1_PDIR_VALID_BIT, .type = 0}
54 };
55
56 static struct _hp_private {
57         volatile u8 *ioc_regs;
58         volatile u8 *lba_regs;
59         int lba_cap_offset;
60         u64 *io_pdir;           // PDIR for entire IOVA
61         u64 *gatt;              // PDIR just for GART (subset of above)
62         u64 gatt_entries;
63         u64 iova_base;
64         u64 gart_base;
65         u64 gart_size;
66         u64 io_pdir_size;
67         int io_pdir_owner;      // do we own it, or share it with sba_iommu?
68         int io_page_size;
69         int io_tlb_shift;
70         int io_tlb_ps;          // IOC ps config
71         int io_pages_per_kpage;
72 } hp_private;
73
74 static int __init hp_zx1_ioc_shared(void)
75 {
76         struct _hp_private *hp = &hp_private;
77
78         printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n");
79
80         /*
81          * IOC already configured by sba_iommu module; just use
82          * its setup.  We assume:
83          *      - IOVA space is 1Gb in size
84          *      - first 512Mb is IOMMU, second 512Mb is GART
85          */
86         hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG);
87         switch (hp->io_tlb_ps) {
88                 case 0: hp->io_tlb_shift = 12; break;
89                 case 1: hp->io_tlb_shift = 13; break;
90                 case 2: hp->io_tlb_shift = 14; break;
91                 case 3: hp->io_tlb_shift = 16; break;
92                 default:
93                         printk(KERN_ERR PFX "Invalid IOTLB page size "
94                                "configuration 0x%x\n", hp->io_tlb_ps);
95                         hp->gatt = 0;
96                         hp->gatt_entries = 0;
97                         return -ENODEV;
98         }
99         hp->io_page_size = 1 << hp->io_tlb_shift;
100         hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
101
102         hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1;
103         hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
104
105         hp->gart_size = HP_ZX1_GART_SIZE;
106         hp->gatt_entries = hp->gart_size / hp->io_page_size;
107
108         hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
109         hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
110
111         if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
112                 /* Normal case when no AGP device in system */
113                 hp->gatt = 0;
114                 hp->gatt_entries = 0;
115                 printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
116                        "GART disabled\n");
117                 return -ENODEV;
118         }
119
120         return 0;
121 }
122
123 static int __init
124 hp_zx1_ioc_owner (void)
125 {
126         struct _hp_private *hp = &hp_private;
127
128         printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n");
129
130         /*
131          * Select an IOV page size no larger than system page size.
132          */
133         if (PAGE_SIZE >= KB(64)) {
134                 hp->io_tlb_shift = 16;
135                 hp->io_tlb_ps = 3;
136         } else if (PAGE_SIZE >= KB(16)) {
137                 hp->io_tlb_shift = 14;
138                 hp->io_tlb_ps = 2;
139         } else if (PAGE_SIZE >= KB(8)) {
140                 hp->io_tlb_shift = 13;
141                 hp->io_tlb_ps = 1;
142         } else {
143                 hp->io_tlb_shift = 12;
144                 hp->io_tlb_ps = 0;
145         }
146         hp->io_page_size = 1 << hp->io_tlb_shift;
147         hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
148
149         hp->iova_base = HP_ZX1_IOVA_BASE;
150         hp->gart_size = HP_ZX1_GART_SIZE;
151         hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size;
152
153         hp->gatt_entries = hp->gart_size / hp->io_page_size;
154         hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64);
155
156         return 0;
157 }
158
159 static int __init
160 hp_zx1_ioc_init (u64 hpa)
161 {
162         struct _hp_private *hp = &hp_private;
163
164         hp->ioc_regs = ioremap(hpa, 1024);
165         if (!hp->ioc_regs)
166                 return -ENOMEM;
167
168         /*
169          * If the IOTLB is currently disabled, we can take it over.
170          * Otherwise, we have to share with sba_iommu.
171          */
172         hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0;
173
174         if (hp->io_pdir_owner)
175                 return hp_zx1_ioc_owner();
176
177         return hp_zx1_ioc_shared();
178 }
179
180 static int
181 hp_zx1_lba_find_capability (volatile u8 *hpa, int cap)
182 {
183         u16 status;
184         u8 pos, id;
185         int ttl = 48;
186
187         status = INREG16(hpa, PCI_STATUS);
188         if (!(status & PCI_STATUS_CAP_LIST))
189                 return 0;
190         pos = INREG8(hpa, PCI_CAPABILITY_LIST);
191         while (ttl-- && pos >= 0x40) {
192                 pos &= ~3;
193                 id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
194                 if (id == 0xff)
195                         break;
196                 if (id == cap)
197                         return pos;
198                 pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
199         }
200         return 0;
201 }
202
203 static int __init
204 hp_zx1_lba_init (u64 hpa)
205 {
206         struct _hp_private *hp = &hp_private;
207         int cap;
208
209         hp->lba_regs = ioremap(hpa, 256);
210         if (!hp->lba_regs)
211                 return -ENOMEM;
212
213         hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
214
215         cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
216         if (cap != PCI_CAP_ID_AGP) {
217                 printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
218                        cap, hp->lba_cap_offset);
219                 return -ENODEV;
220         }
221
222         return 0;
223 }
224
225 static int
226 hp_zx1_fetch_size(void)
227 {
228         int size;
229
230         size = hp_private.gart_size / MB(1);
231         hp_zx1_sizes[0].size = size;
232         agp_bridge->current_size = (void *) &hp_zx1_sizes[0];
233         return size;
234 }
235
236 static int
237 hp_zx1_configure (void)
238 {
239         struct _hp_private *hp = &hp_private;
240
241         agp_bridge->gart_bus_addr = hp->gart_base;
242         agp_bridge->capndx = hp->lba_cap_offset;
243         agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
244
245         if (hp->io_pdir_owner) {
246                 OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir));
247                 OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
248                 OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
249                 OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
250                 OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
251                 INREG64(hp->ioc_regs, HP_ZX1_PCOM);
252         }
253
254         return 0;
255 }
256
257 static void
258 hp_zx1_cleanup (void)
259 {
260         struct _hp_private *hp = &hp_private;
261
262         if (hp->ioc_regs) {
263                 if (hp->io_pdir_owner)
264                         OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
265                 iounmap((void *) hp->ioc_regs);
266         }
267         if (hp->lba_regs)
268                 iounmap((void *) hp->lba_regs);
269 }
270
271 static void
272 hp_zx1_tlbflush (struct agp_memory *mem)
273 {
274         struct _hp_private *hp = &hp_private;
275
276         OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->gart_base | log2(hp->gart_size));
277         INREG64(hp->ioc_regs, HP_ZX1_PCOM);
278 }
279
280 static int
281 hp_zx1_create_gatt_table (void)
282 {
283         struct _hp_private *hp = &hp_private;
284         int i;
285
286         if (hp->io_pdir_owner) {
287                 hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL,
288                                                 get_order(hp->io_pdir_size));
289                 if (!hp->io_pdir) {
290                         printk(KERN_ERR PFX "Couldn't allocate contiguous "
291                                 "memory for I/O PDIR\n");
292                         hp->gatt = 0;
293                         hp->gatt_entries = 0;
294                         return -ENOMEM;
295                 }
296                 memset(hp->io_pdir, 0, hp->io_pdir_size);
297
298                 hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
299         }
300
301         for (i = 0; i < hp->gatt_entries; i++) {
302                 hp->gatt[i] = (unsigned long) agp_bridge->scratch_page;
303         }
304
305         return 0;
306 }
307
308 static int
309 hp_zx1_free_gatt_table (void)
310 {
311         struct _hp_private *hp = &hp_private;
312
313         if (hp->io_pdir_owner)
314                 free_pages((unsigned long) hp->io_pdir,
315                             get_order(hp->io_pdir_size));
316         else
317                 hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE;
318         return 0;
319 }
320
321 static int
322 hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
323 {
324         struct _hp_private *hp = &hp_private;
325         int i, k;
326         off_t j, io_pg_start;
327         int io_pg_count;
328
329         if (type != 0 || mem->type != 0) {
330                 return -EINVAL;
331         }
332
333         io_pg_start = hp->io_pages_per_kpage * pg_start;
334         io_pg_count = hp->io_pages_per_kpage * mem->page_count;
335         if ((io_pg_start + io_pg_count) > hp->gatt_entries) {
336                 return -EINVAL;
337         }
338
339         j = io_pg_start;
340         while (j < (io_pg_start + io_pg_count)) {
341                 if (hp->gatt[j]) {
342                         return -EBUSY;
343                 }
344                 j++;
345         }
346
347         if (mem->is_flushed == FALSE) {
348                 global_cache_flush();
349                 mem->is_flushed = TRUE;
350         }
351
352         for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
353                 unsigned long paddr;
354
355                 paddr = mem->memory[i];
356                 for (k = 0;
357                      k < hp->io_pages_per_kpage;
358                      k++, j++, paddr += hp->io_page_size) {
359                         hp->gatt[j] = agp_bridge->driver->mask_memory(paddr, type);
360                 }
361         }
362
363         agp_bridge->driver->tlb_flush(mem);
364         return 0;
365 }
366
367 static int
368 hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
369 {
370         struct _hp_private *hp = &hp_private;
371         int i, io_pg_start, io_pg_count;
372
373         if (type != 0 || mem->type != 0) {
374                 return -EINVAL;
375         }
376
377         io_pg_start = hp->io_pages_per_kpage * pg_start;
378         io_pg_count = hp->io_pages_per_kpage * mem->page_count;
379         for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
380                 hp->gatt[i] = agp_bridge->scratch_page;
381         }
382
383         agp_bridge->driver->tlb_flush(mem);
384         return 0;
385 }
386
387 static unsigned long
388 hp_zx1_mask_memory (unsigned long addr, int type)
389 {
390         return HP_ZX1_PDIR_VALID_BIT | addr;
391 }
392
393 static void
394 hp_zx1_enable (u32 mode)
395 {
396         struct _hp_private *hp = &hp_private;
397         u32 command;
398
399         command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
400
401         command = agp_collect_device_status(mode, command);
402         command |= 0x00000100;
403
404         OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
405
406         agp_device_command(command, (mode & AGP8X_MODE) != 0);
407 }
408
409 struct agp_bridge_driver hp_zx1_driver = {
410         .owner                  = THIS_MODULE,
411         .size_type              = FIXED_APER_SIZE,
412         .configure              = hp_zx1_configure,
413         .fetch_size             = hp_zx1_fetch_size,
414         .cleanup                = hp_zx1_cleanup,
415         .tlb_flush              = hp_zx1_tlbflush,
416         .mask_memory            = hp_zx1_mask_memory,
417         .masks                  = hp_zx1_masks,
418         .agp_enable             = hp_zx1_enable,
419         .cache_flush            = global_cache_flush,
420         .create_gatt_table      = hp_zx1_create_gatt_table,
421         .free_gatt_table        = hp_zx1_free_gatt_table,
422         .insert_memory          = hp_zx1_insert_memory,
423         .remove_memory          = hp_zx1_remove_memory,
424         .alloc_by_type          = agp_generic_alloc_by_type,
425         .free_by_type           = agp_generic_free_by_type,
426         .agp_alloc_page         = agp_generic_alloc_page,
427         .agp_destroy_page       = agp_generic_destroy_page,
428         .cant_use_aperture      = 1,
429 };
430
431 static int __init
432 hp_zx1_setup (u64 ioc_hpa, u64 lba_hpa)
433 {
434         struct agp_bridge_data *bridge;
435         int error = 0;
436
437         error = hp_zx1_ioc_init(ioc_hpa);
438         if (error)
439                 goto fail;
440
441         error = hp_zx1_lba_init(lba_hpa);
442         if (error)
443                 goto fail;
444
445         bridge = agp_alloc_bridge();
446         if (!bridge) {
447                 error = -ENOMEM;
448                 goto fail;
449         }
450         bridge->driver = &hp_zx1_driver;
451
452         fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
453         fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
454         bridge->dev = &fake_bridge_dev;
455
456         error = agp_add_bridge(bridge);
457   fail:
458         if (error)
459                 hp_zx1_cleanup();
460         return error;
461 }
462
463 static acpi_status __init
464 zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
465 {
466         acpi_handle handle, parent;
467         acpi_status status;
468         struct acpi_buffer buffer;
469         struct acpi_device_info *info;
470         u64 lba_hpa, sba_hpa, length;
471         int match;
472
473         status = hp_acpi_csr_space(obj, &lba_hpa, &length);
474         if (ACPI_FAILURE(status))
475                 return AE_OK; /* keep looking for another bridge */
476
477         /* Look for an enclosing IOC scope and find its CSR space */
478         handle = obj;
479         do {
480                 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
481                 status = acpi_get_object_info(handle, &buffer);
482                 if (ACPI_SUCCESS(status)) {
483                         /* TBD check _CID also */
484                         info = buffer.pointer;
485                         info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0';
486                         match = (strcmp(info->hardware_id.value, "HWP0001") == 0);
487                         ACPI_MEM_FREE(info);
488                         if (match) {
489                                 status = hp_acpi_csr_space(handle, &sba_hpa, &length);
490                                 if (ACPI_SUCCESS(status))
491                                         break;
492                                 else {
493                                         printk(KERN_ERR PFX "Detected HP ZX1 "
494                                                "AGP LBA but no IOC.\n");
495                                         return AE_OK;
496                                 }
497                         }
498                 }
499
500                 status = acpi_get_parent(handle, &parent);
501                 handle = parent;
502         } while (ACPI_SUCCESS(status));
503
504         if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
505                 return AE_OK;
506
507         printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset (ioc=%lx, lba=%lx)\n",
508                 (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
509
510         hp_zx1_gart_found = 1;
511         return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
512 }
513
514 static int __init
515 agp_hp_init (void)
516 {
517
518         acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
519         if (hp_zx1_gart_found)
520                 return 0;
521
522         acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
523         if (hp_zx1_gart_found)
524                 return 0;
525
526         return -ENODEV;
527 }
528
529 static void __exit
530 agp_hp_cleanup (void)
531 {
532 }
533
534 module_init(agp_hp_init);
535 module_exit(agp_hp_cleanup);
536
537 MODULE_LICENSE("GPL and additional rights");